diff --git a/modules b/modules index f055eb6a..727f468c 100644 --- a/modules +++ b/modules @@ -1,7 +1,7 @@ GLUON_FEEDS='openwrt gluon routing luci' OPENWRT_REPO=git://git.openwrt.org/12.09/openwrt.git -OPENWRT_COMMIT=5180b2c94cd0b270b7290e84607877db76855b49 +OPENWRT_COMMIT=595ebf6f0d39394e5518869d4fc436cfd27e4d3c PACKAGES_OPENWRT_REPO=git://git.openwrt.org/12.09/packages.git PACKAGES_OPENWRT_COMMIT=381bbea65989b63e30f43ab87e51b042325bbff3 diff --git a/patches/openwrt/0018-Backport-mac80211-from-Barrier-Breaker-r41113.patch b/patches/openwrt/0018-Backport-mac80211-from-Barrier-Breaker-r41113.patch deleted file mode 100644 index 9e7f6e85..00000000 --- a/patches/openwrt/0018-Backport-mac80211-from-Barrier-Breaker-r41113.patch +++ /dev/null @@ -1,15067 +0,0 @@ -From: Matthias Schiffer -Date: Mon, 19 May 2014 15:59:37 +0200 -Subject: Backport mac80211 from Barrier Breaker (r41113) - -diff --git a/package/mac80211/Makefile b/package/mac80211/Makefile -index 9a7093c..c286b0f 100644 ---- a/package/mac80211/Makefile -+++ b/package/mac80211/Makefile -@@ -1,5 +1,5 @@ - # --# Copyright (C) 2007-2013 OpenWrt.org -+# Copyright (C) 2007-2014 OpenWrt.org - # - # This is free software, licensed under the GNU General Public License v2. - # See /LICENSE for more information. -@@ -10,11 +10,11 @@ include $(INCLUDE_DIR)/kernel.mk - - PKG_NAME:=mac80211 - --PKG_VERSION:=2014-01-23.1 -+PKG_VERSION:=2014-05-22 - PKG_RELEASE:=1 - PKG_SOURCE_URL:=http://mirror2.openwrt.org/sources - PKG_BACKPORT_VERSION:= --PKG_MD5SUM:=8db16edbdaf4abc2e9c2f3b6c86736a6 -+PKG_MD5SUM:=367937d4f8c05cb36ca989ee26abc3df - - PKG_SOURCE:=compat-wireless-$(PKG_VERSION)$(PKG_BACKPORT_VERSION).tar.bz2 - PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/compat-wireless-$(PKG_VERSION) -@@ -105,12 +105,12 @@ Generic IEEE 802.11 Networking Stack (mac80211) - endef - - PKG_LINUX_FIRMWARE_NAME:=linux-firmware --PKG_LINUX_FIRMWARE_VERSION:=7d0c7a8cfd78388d90cc784a185b19dcbdbce824 -+PKG_LINUX_FIRMWARE_VERSION:=f8c22c692bdee57a20b092e647464ff6176df3ed - 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.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:=837a1a9456c1ec8b428cc0b2b08a331b -+PKG_LINUX_FIRMWARE_MIRROR_MD5SUM:=e219333f01835c6e556875a9e0deb3f9 - - define Download/linux-firmware - FILE:=$(PKG_LINUX_FIRMWARE_SOURCE) -@@ -124,7 +124,7 @@ endef - $(eval $(call Download,linux-firmware)) - - PKG_ATH10K_LINUX_FIRMWARE_NAME:=ath10k-firmware --PKG_ATH10K_LINUX_FIRMWARE_VERSION:=d86e78e5c6be34329936c8bd73a212700437be2e -+PKG_ATH10K_LINUX_FIRMWARE_VERSION:=38eeda3ae6f90fde5546bdd48ee4ff3090f238c0 - PKG_ATH10K_LINUX_FIRMWARE_SOURCE:=$(PKG_ATH10K_LINUX_FIRMWARE_NAME)-$(PKG_ATH10K_LINUX_FIRMWARE_VERSION).tar.bz2 - PKG_ATH10K_LINUX_FIRMWARE_PROTO:=git - PKG_ATH10K_LINUX_FIRMWARE_SOURCE_URL:=https://github.com/kvalo/ath10k-firmware.git -@@ -363,8 +363,8 @@ define KernelPackage/rtl8180 - $(call KernelPackage/rtl818x/Default) - DEPENDS+= @PCI_SUPPORT - TITLE+= (RTL8180 PCI) -- FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/rtl818x/rtl8180/rtl8180.ko -- AUTOLOAD:=$(call AutoLoad,27,rtl8180) -+ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/rtl818x/rtl8180/rtl818x_pci.ko -+ AUTOLOAD:=$(call AutoLoad,27,rtl818x_pci) - endef - - define KernelPackage/rtl8187 -@@ -606,6 +606,19 @@ Atheros IEEE 802.11ac family of chipsets. For now only - PCI is supported. - endef - -+define KernelPackage/ath10k/config -+ if PACKAGE_kmod-ath10k -+ -+ config ATH10K_STA_FW -+ bool "Firmware optimized for STA operation" -+ default n -+ help -+ Use the ath10k firmware optimized for wireless client instead -+ of access point operation. -+ -+ endif -+endef -+ - define KernelPackage/carl9170 - $(call KernelPackage/mac80211/Default) - TITLE:=Driver for Atheros AR9170 USB sticks -@@ -844,6 +857,13 @@ define KernelPackage/iwlagn/config - Download and install firmware for: - Intel Centrino Advanced-N 6230, Wireless-N 1030, Wireless-N 130 and Advanced-N 6235 - -+ config IWL7260_FW -+ bool "Intel 7260 Firmware" -+ default y -+ help -+ Download and install firmware for: -+ Intel Dual Band Wireless-N 7260 and Intel Dual Band Wireless-AC 7260 -+ - config IWL100_FW - bool "Intel 100 Firmware" - default y -@@ -1639,8 +1659,7 @@ define KernelPackage/wl18xx/install - $(INSTALL_DIR) $(1)/lib/firmware/ti-connectivity - $(INSTALL_DATA) \ - $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/ti-connectivity/wl18xx-conf.bin \ -- $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/ti-connectivity/wl18xx-fw.bin \ -- $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/ti-connectivity/wl18xx-fw-2.bin \ -+ $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/ti-connectivity/wl18xx-fw-3.bin \ - $(1)/lib/firmware/ti-connectivity - endef - -@@ -1664,10 +1683,19 @@ endef - - define KernelPackage/ath10k/install - $(INSTALL_DIR) $(1)/lib/firmware/ath10k/QCA988X/hw2.0 -+ifeq ($(CONFIG_ATH10K_STA_FW),y) -+ $(INSTALL_DATA) \ -+ $(PKG_BUILD_DIR)/$(PKG_ATH10K_LINUX_FIRMWARE_SUBDIR)/ath10k/QCA988X/hw2.0/board.bin \ -+ $(1)/lib/firmware/ath10k/QCA988X/hw2.0/ -+ $(INSTALL_DATA) \ -+ $(PKG_BUILD_DIR)/$(PKG_ATH10K_LINUX_FIRMWARE_SUBDIR)/main/firmware-2.bin_999.999.0.636 \ -+ $(1)/lib/firmware/ath10k/QCA988X/hw2.0/firmware-2.bin -+else - $(INSTALL_DATA) \ - $(PKG_BUILD_DIR)/$(PKG_ATH10K_LINUX_FIRMWARE_SUBDIR)/ath10k/QCA988X/hw2.0/board.bin \ - $(PKG_BUILD_DIR)/$(PKG_ATH10K_LINUX_FIRMWARE_SUBDIR)/ath10k/QCA988X/hw2.0/firmware-2.bin \ - $(1)/lib/firmware/ath10k/QCA988X/hw2.0/ -+endif - endef - - define KernelPackage/mwl8k/install -@@ -1714,6 +1742,9 @@ endif - ifneq ($(CONFIG_IWL6030_FW),) - $(INSTALL_DATA) $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/iwlwifi-6000g2b-6.ucode $(1)/lib/firmware - endif -+ifneq ($(CONFIG_IWL7260_FW),) -+ $(INSTALL_DATA) $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/iwlwifi-7260-7.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 -diff --git a/package/mac80211/files/regdb.txt b/package/mac80211/files/regdb.txt -index 2badb21..fcab208 100644 ---- a/package/mac80211/files/regdb.txt -+++ b/package/mac80211/files/regdb.txt -@@ -1,211 +1,216 @@ - # This is the world regulatory domain - country 00: -- (2402 - 2472 @ 40), (3, 20) -+ (2402 - 2472 @ 40), (20) - # Channel 12 - 13. -- (2457 - 2482 @ 40), (3, 20), PASSIVE-SCAN, NO-IBSS -+ (2457 - 2482 @ 40), (20), NO-IR - # Channel 14. Only JP enables this and for 802.11b only -- (2474 - 2494 @ 20), (3, 20), PASSIVE-SCAN, NO-IBSS, NO-OFDM -+ (2474 - 2494 @ 20), (20), NO-IR - # Channel 36 - 48 -- (5170 - 5250 @ 80), (3, 20) -+ (5170 - 5250 @ 80), (20), NO-IR - # NB: 5260 MHz - 5700 MHz requies DFS - # Channel 149 - 165 -- (5735 - 5835 @ 80), (3, 20), PASSIVE-SCAN, NO-IBSS -+ (5735 - 5835 @ 80), (20), NO-IR - # IEEE 802.11ad (60GHz), channels 1..3 -- (57240 - 63720 @ 2160), (N/A, 0) -+ (57240 - 63720 @ 2160), (0) - - - country AD: - # 60 gHz band channels 1-4, ref: Etsi En 302 567 -- (57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR -- --country AE: -- (2402 - 2482 @ 40), (N/A, 20) -- (5170 - 5250 @ 80), (3, 17) -- (5250 - 5330 @ 80), (3, 24), DFS -- (5490 - 5710 @ 80), (3, 24), DFS -- (5735 - 5835 @ 80), (3, 30) -- --country AL: -- (2402 - 2482 @ 20), (N/A, 20) -- --country AM: -- (2402 - 2482 @ 40), (N/A, 20) -- (5170 - 5250 @ 20), (N/A, 18) -- (5250 - 5330 @ 20), (N/A, 18), DFS -- --country AN: -- (2402 - 2482 @ 40), (N/A, 20) -- (5170 - 5250 @ 40), (N/A, 20) -- (5250 - 5330 @ 40), (N/A, 20), DFS -- (5490 - 5710 @ 40), (N/A, 27), DFS -- --country AR: -- (2402 - 2482 @ 40), (N/A, 20) -- (5170 - 5250 @ 80), (3, 17) -- (5250 - 5330 @ 80), (3, 24), DFS -- (5490 - 5710 @ 80), (3, 24), DFS -- (5735 - 5835 @ 80), (3, 30) -+ (57240 - 65880 @ 2160), (40), NO-OUTDOOR -+ -+country AE: DFS-FCC -+ (2402 - 2482 @ 40), (20) -+ (5170 - 5250 @ 80), (17) -+ (5250 - 5330 @ 80), (24), DFS -+ (5490 - 5730 @ 80), (24), DFS -+ (5735 - 5835 @ 80), (30) -+ -+country AL: DFS-ETSI -+ (2402 - 2482 @ 40), (20) -+ (5170 - 5250 @ 80), (20.00) -+ (5250 - 5330 @ 80), (20.00), DFS -+ (5490 - 5710 @ 80), (27.00), DFS -+ -+country AM: DFS-ETSI -+ (2402 - 2482 @ 40), (20) -+ (5170 - 5250 @ 80), (18) -+ (5250 - 5330 @ 80), (18), DFS -+ -+country AN: DFS-ETSI -+ (2402 - 2482 @ 40), (20) -+ (5170 - 5250 @ 80), (20) -+ (5250 - 5330 @ 80), (20), DFS -+ (5490 - 5710 @ 80), (27), DFS -+ -+country AR: DFS-FCC -+ (2402 - 2482 @ 40), (20) -+ (5170 - 5250 @ 80), (17) -+ (5250 - 5330 @ 80), (24), DFS -+ (5490 - 5730 @ 80), (24), DFS -+ (5735 - 5835 @ 80), (30) - - country AT: DFS-ETSI -- (2402 - 2482 @ 40), (N/A, 20) -- (5170 - 5250 @ 80), (N/A, 20) -- (5250 - 5330 @ 80), (N/A, 20), DFS -- (5490 - 5710 @ 80), (N/A, 27), DFS -+ (2402 - 2482 @ 40), (20) -+ (5170 - 5250 @ 80), (20) -+ (5250 - 5330 @ 80), (20), DFS -+ (5490 - 5710 @ 80), (27), DFS - # 60 gHz band channels 1-4, ref: Etsi En 302 567 -- (57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR -+ (57240 - 65880 @ 2160), (40), NO-OUTDOOR - - country AU: -- (2402 - 2482 @ 40), (N/A, 20) -- (5170 - 5250 @ 80), (3, 17) -- (5250 - 5330 @ 80), (3, 24), DFS -- (5490 - 5710 @ 80), (3, 24), DFS -- (5735 - 5835 @ 80), (3, 30) -- --country AW: -- (2402 - 2482 @ 40), (N/A, 20) -- (5170 - 5250 @ 40), (N/A, 20) -- (5250 - 5330 @ 40), (N/A, 20), DFS -- (5490 - 5710 @ 40), (N/A, 27), DFS -- --country AZ: -- (2402 - 2482 @ 40), (N/A, 20) -- (5170 - 5250 @ 40), (N/A, 18) -- (5250 - 5330 @ 40), (N/A, 18), DFS -+ (2402 - 2482 @ 40), (20) -+ (5170 - 5250 @ 80), (17) -+ (5250 - 5330 @ 80), (24), DFS -+ (5490 - 5710 @ 80), (24), DFS -+ (5735 - 5835 @ 80), (30) -+ -+country AW: DFS-ETSI -+ (2402 - 2482 @ 40), (20) -+ (5170 - 5250 @ 80), (20) -+ (5250 - 5330 @ 80), (20), DFS -+ (5490 - 5710 @ 80), (27), DFS -+ -+country AZ: DFS-ETSI -+ (2402 - 2482 @ 40), (20) -+ (5170 - 5250 @ 80), (18) -+ (5250 - 5330 @ 80), (18), DFS - - country BA: DFS-ETSI -- (2402 - 2482 @ 40), (N/A, 20) -- (5170 - 5250 @ 40), (N/A, 20) -- (5250 - 5330 @ 40), (N/A, 20), DFS -- (5490 - 5710 @ 40), (N/A, 27), DFS -+ (2402 - 2482 @ 40), (20) -+ (5170 - 5250 @ 80), (20) -+ (5250 - 5330 @ 80), (20), DFS -+ (5490 - 5710 @ 80), (27), DFS - # 60 gHz band channels 1-4, ref: Etsi En 302 567 -- (57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR -+ (57240 - 65880 @ 2160), (40), NO-OUTDOOR - --country BB: -- (2402 - 2482 @ 40), (N/A, 20) -- (5170 - 5250 @ 40), (3, 23) -- (5250 - 5330 @ 40), (3, 23), DFS -- (5735 - 5835 @ 40), (3, 30) -+country BB: DFS-FCC -+ (2402 - 2482 @ 40), (20) -+ (5170 - 5250 @ 80), (23) -+ (5250 - 5330 @ 80), (23), DFS -+ (5735 - 5835 @ 80), (30) - --country BD: -- (2402 - 2482 @ 40), (N/A, 20) -+country BD: DFS-JP -+ (2402 - 2482 @ 40), (20) -+ (5735 - 5835 @ 80), (30) - - country BE: DFS-ETSI -- (2402 - 2482 @ 40), (N/A, 20) -- (5170 - 5250 @ 80), (N/A, 20) -- (5250 - 5330 @ 80), (N/A, 20), DFS -- (5490 - 5710 @ 80), (N/A, 27), DFS -+ (2402 - 2482 @ 40), (20) -+ (5170 - 5250 @ 80), (20) -+ (5250 - 5330 @ 80), (20), DFS -+ (5490 - 5710 @ 80), (27), DFS - # 60 gHz band channels 1-4, ref: Etsi En 302 567 -- (57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR -+ (57240 - 65880 @ 2160), (40), NO-OUTDOOR - - country BG: DFS-ETSI -- (2402 - 2482 @ 40), (N/A, 20) -- (5170 - 5250 @ 40), (N/A, 23) -- (5250 - 5290 @ 40), (N/A, 23), DFS -- (5490 - 5710 @ 40), (N/A, 30), DFS -+ (2402 - 2482 @ 40), (20) -+ (5170 - 5250 @ 80), (20) -+ (5250 - 5330 @ 80), (20), DFS - # 60 gHz band channels 1-4, ref: Etsi En 302 567 -- (57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR -+ (57240 - 65880 @ 2160), (40), NO-OUTDOOR - --country BH: -- (2402 - 2482 @ 40), (N/A, 20) -- (5170 - 5250 @ 20), (N/A, 20) -- (5250 - 5330 @ 20), (N/A, 20), DFS -- (5735 - 5835 @ 20), (N/A, 20) -+country BH: DFS-JP -+ (2402 - 2482 @ 40), (20) -+ (5170 - 5250 @ 80), (20) -+ (5250 - 5330 @ 80), (20), DFS -+ (5735 - 5835 @ 80), (20) - - country BL: -- (2402 - 2482 @ 40), (N/A, 20) -- (5170 - 5250 @ 40), (N/A, 18) -- (5250 - 5330 @ 40), (N/A, 18), DFS -- --country BN: -- (2402 - 2482 @ 40), (N/A, 20) -- (5170 - 5250 @ 40), (N/A, 20) -- (5250 - 5330 @ 40), (N/A, 20), DFS -- (5735 - 5835 @ 40), (N/A, 30) -- --country BO: -- (2402 - 2482 @ 40), (N/A, 30) -- (5735 - 5835 @ 40), (N/A, 30) -- --country BR: -- (2402 - 2482 @ 40), (N/A, 20) -- (5170 - 5250 @ 80), (3, 17) -- (5250 - 5330 @ 80), (3, 24), DFS -- (5490 - 5710 @ 80), (3, 24), DFS -- (5735 - 5835 @ 80), (3, 30) -- --country BY: -- (2402 - 2482 @ 40), (N/A, 20) -- (5170 - 5250 @ 40), (N/A, 20) -- (5250 - 5330 @ 40), (N/A, 20), DFS -- (5490 - 5710 @ 40), (N/A, 27), DFS -- --country BZ: -- (2402 - 2482 @ 40), (N/A, 30) -- (5735 - 5835 @ 40), (N/A, 30) -- --country CA: -- (2402 - 2472 @ 40), (3, 27) -- (5170 - 5250 @ 80), (3, 17) -- (5250 - 5330 @ 80), (3, 24), DFS -- (5490 - 5710 @ 80), (3, 24), DFS -- (5735 - 5835 @ 80), (3, 30) -+ (2402 - 2482 @ 40), (20) -+ (5170 - 5250 @ 40), (18) -+ (5250 - 5330 @ 40), (18), DFS -+ -+country BN: DFS-JP -+ (2402 - 2482 @ 40), (20) -+ (5170 - 5250 @ 80), (20) -+ (5250 - 5330 @ 80), (20), DFS -+ (5735 - 5835 @ 80), (20) -+ -+country BO: DFS-JP -+ (2402 - 2482 @ 40), (30) -+ (5735 - 5835 @ 80), (30) -+ -+country BR: DFS-FCC -+ (2402 - 2482 @ 40), (20) -+ (5170 - 5250 @ 80), (17) -+ (5250 - 5330 @ 80), (24), DFS -+ (5490 - 5730 @ 80), (24), DFS -+ (5735 - 5835 @ 80), (30) -+ -+country BY: DFS-ETSI -+ (2402 - 2482 @ 40), (20) -+ (5170 - 5250 @ 80), (20) -+ (5250 - 5330 @ 80), (20), DFS -+ (5490 - 5710 @ 80), (27), DFS -+ -+country BZ: DFS-JP -+ (2402 - 2482 @ 40), (30) -+ (5735 - 5835 @ 80), (30) -+ -+country CA: DFS-FCC -+ (2402 - 2472 @ 40), (30) -+ (5170 - 5250 @ 80), (17) -+ (5250 - 5330 @ 80), (24), DFS -+ (5490 - 5730 @ 80), (24), DFS -+ (5735 - 5835 @ 80), (30) - - country CH: DFS-ETSI -- (2402 - 2482 @ 40), (N/A, 20) -- (5170 - 5250 @ 80), (N/A, 20) -- (5250 - 5330 @ 80), (N/A, 20), DFS -- (5490 - 5710 @ 80), (N/A, 27), DFS -- # 60 gHz band channels 1-4, ref: Etsi En 302 567 -- (57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR -- --country CL: -- (2402 - 2482 @ 40), (N/A, 20) -- (5170 - 5250 @ 40), (N/A, 20) -- (5250 - 5330 @ 40), (N/A, 20), DFS -- (5735 - 5835 @ 40), (N/A, 20) -- --country CN: -- (2402 - 2482 @ 40), (N/A, 20) -- (5735 - 5835 @ 80), (N/A, 30) -+ (2402 - 2482 @ 40), (20) -+ (5170 - 5250 @ 80), (20) -+ (5250 - 5330 @ 80), (20), DFS -+ (5490 - 5710 @ 80), (27), DFS -+ # 60 gHz band channels 1-4, ref: Etsi En 302 567 -+ (57240 - 65880 @ 2160), (40), NO-OUTDOOR -+ -+country CL: DFS-JP -+ (2402 - 2482 @ 40), (20) -+ (5170 - 5250 @ 80), (20) -+ (5250 - 5330 @ 80), (20), DFS -+ (5735 - 5835 @ 80), (20) -+ -+country CN: DFS-FCC -+ (2402 - 2482 @ 40), (20) -+ (5170 - 5250 @ 80), (23) -+ (5250 - 5330 @ 80), (23), DFS -+ (5735 - 5835 @ 80), (30) - # 60 gHz band channels 1,4: 28dBm, channels 2,3: 44dBm - # ref: http://www.miit.gov.cn/n11293472/n11505629/n11506593/n11960250/n11960606/n11960700/n12330791.files/n12330790.pdf -- (57240 - 59400 @ 2160), (N/A, 28) -- (59400 - 63720 @ 2160), (N/A, 44) -- (63720 - 65880 @ 2160), (N/A, 28) -- --country CO: -- (2402 - 2472 @ 40), (3, 27) -- (5170 - 5250 @ 80), (3, 17) -- (5250 - 5330 @ 80), (3, 24), DFS -- (5490 - 5710 @ 80), (3, 24), DFS -- (5735 - 5835 @ 80), (3, 30) -- --country CR: -- (2402 - 2482 @ 40), (N/A, 20) -- (5170 - 5250 @ 80), (3, 17) -- (5250 - 5330 @ 80), (3, 24), DFS -- (5490 - 5710 @ 80), (3, 24), DFS -- (5735 - 5835 @ 80), (3, 30) -+ (57240 - 59400 @ 2160), (28) -+ (59400 - 63720 @ 2160), (44) -+ (63720 - 65880 @ 2160), (28) -+ -+country CO: DFS-FCC -+ (2402 - 2482 @ 40), (20) -+ (5170 - 5250 @ 80), (17) -+ (5250 - 5330 @ 80), (24), DFS -+ (5490 - 5730 @ 80), (24), DFS -+ (5735 - 5835 @ 80), (30) -+ -+country CR: DFS-FCC -+ (2402 - 2482 @ 40), (20) -+ (5170 - 5250 @ 80), (17) -+ (5250 - 5330 @ 80), (24), DFS -+ (5490 - 5730 @ 80), (24), DFS -+ (5735 - 5835 @ 80), (30) - - country CY: DFS-ETSI -- (2402 - 2482 @ 40), (N/A, 20) -- (5170 - 5250 @ 40), (N/A, 20) -- (5250 - 5330 @ 40), (N/A, 20), DFS -- (5490 - 5710 @ 40), (N/A, 27), DFS -+ (2402 - 2482 @ 40), (20) -+ (5170 - 5250 @ 80), (20) -+ (5250 - 5330 @ 80), (20), DFS -+ (5490 - 5710 @ 80), (27), DFS - # 60 gHz band channels 1-4, ref: Etsi En 302 567 -- (57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR -+ (57240 - 65880 @ 2160), (40), NO-OUTDOOR - - # Data from http://www.ctu.eu/164/download/VOR/VOR-12-08-2005-34.pdf - # and http://www.ctu.eu/164/download/VOR/VOR-12-05-2007-6-AN.pdf - # Power at 5250 - 5350 MHz and 5470 - 5725 MHz can be doubled if TPC is - # implemented. - country CZ: DFS-ETSI -- (2400 - 2483.5 @ 40), (N/A, 100 mW) -- (5150 - 5250 @ 80), (N/A, 200 mW), NO-OUTDOOR -- (5250 - 5350 @ 80), (N/A, 100 mW), NO-OUTDOOR, DFS -- (5470 - 5725 @ 80), (N/A, 500 mW), DFS -+ (2400 - 2483.5 @ 40), (100 mW) -+ (5150 - 5250 @ 80), (200 mW), NO-OUTDOOR -+ (5250 - 5350 @ 80), (100 mW), NO-OUTDOOR -+ (5470 - 5725 @ 80), (500 mW), DFS - # 60 gHz band channels 1-4, ref: Etsi En 302 567 -- (57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR -+ (57240 - 65880 @ 2160), (40), NO-OUTDOOR - - # Data from "Frequenznutzungsplan" (as published in April 2008), downloaded from - # http://www.bundesnetzagentur.de/cae/servlet/contentblob/38448/publicationFile/2659/Frequenznutzungsplan2008_Id17448pdf.pdf -@@ -221,542 +226,555 @@ country CZ: DFS-ETSI - - country DE: DFS-ETSI - # entries 279004 and 280006 -- (2400 - 2483.5 @ 40), (N/A, 100 mW) -- # entry 303005 -- (5150 - 5250 @ 80), (N/A, 100 mW), NO-OUTDOOR -- # entries 304002 and 305002 -- (5250 - 5350 @ 80), (N/A, 100 mW), NO-OUTDOOR, DFS -+ (2400 - 2483.5 @ 40), (100 mW) -+ # entry 303005, 304002 and 305002 -+ (5150 - 5350 @ 80), (100 mW), NO-OUTDOOR - # entries 308002, 309001 and 310003 -- (5470 - 5725 @ 80), (N/A, 500 mW), DFS -+ (5470 - 5725 @ 80), (500 mW), DFS - # 60 gHz band channels 1-4, ref: Etsi En 302 567 -- (57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR -+ (57240 - 65880 @ 2160), (40), NO-OUTDOOR - - country DK: DFS-ETSI -- (2402 - 2482 @ 40), (N/A, 20) -- (5170 - 5250 @ 80), (N/A, 20) -- (5250 - 5330 @ 80), (N/A, 20), DFS -- (5490 - 5710 @ 80), (N/A, 27), DFS -- # 60 gHz band channels 1-4, ref: Etsi En 302 567 -- (57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR -- --country DO: -- (2402 - 2472 @ 40), (3, 27) -- (5170 - 5250 @ 40), (3, 17) -- (5250 - 5330 @ 40), (3, 23), DFS -- (5735 - 5835 @ 40), (3, 30) -- --country DZ: -- (2402 - 2482 @ 40), (N/A, 20) -- --country EC: -- (2402 - 2482 @ 40), (N/A, 20) -- (5170 - 5250 @ 80), (3, 17) -- (5250 - 5330 @ 80), (3, 24), DFS -- (5490 - 5710 @ 80), (3, 24), DFS -- (5735 - 5835 @ 80), (3, 30) -+ (2402 - 2482 @ 40), (20) -+ (5170 - 5250 @ 80), (20) -+ (5250 - 5330 @ 80), (20), DFS -+ (5490 - 5710 @ 80), (27), DFS -+ # 60 gHz band channels 1-4, ref: Etsi En 302 567 -+ (57240 - 65880 @ 2160), (40), NO-OUTDOOR -+ -+country DO: DFS-FCC -+ (2402 - 2472 @ 40), (30) -+ (5170 - 5250 @ 80), (17) -+ (5250 - 5330 @ 80), (23), DFS -+ (5735 - 5835 @ 80), (30) -+ -+country DZ: DFS-JP -+ (2402 - 2482 @ 40), (20) -+ (5170.000 - 5250.000 @ 80.000), (23.00) -+ (5250.000 - 5330.000 @ 80.000), (23.00), DFS -+ (5490.000 - 5670.000 @ 80.000), (23.00), DFS -+ -+country EC: DFS-FCC -+ (2402 - 2482 @ 40), (20) -+ (5170 - 5250 @ 80), (17) -+ (5250 - 5330 @ 80), (24), DFS -+ (5490 - 5730 @ 80), (24), DFS -+ (5735 - 5835 @ 80), (30) - - country EE: DFS-ETSI -- (2402 - 2482 @ 40), (N/A, 20) -- (5170 - 5250 @ 40), (N/A, 20) -- (5250 - 5330 @ 40), (N/A, 20), DFS -- (5490 - 5710 @ 40), (N/A, 27), DFS -+ (2402 - 2482 @ 40), (20) -+ (5170 - 5250 @ 80), (20) -+ (5250 - 5330 @ 80), (20), DFS -+ (5490 - 5710 @ 80), (27), DFS - # 60 gHz band channels 1-4, ref: Etsi En 302 567 -- (57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR -+ (57240 - 65880 @ 2160), (40), NO-OUTDOOR - --country EG: -- (2402 - 2482 @ 40), (N/A, 20) -- (5170 - 5250 @ 20), (N/A, 20) -- (5250 - 5330 @ 20), (N/A, 20), DFS -+country EG: DFS-ETSI -+ (2402 - 2482 @ 40), (20) -+ (5170 - 5250 @ 80), (20) -+ (5250 - 5330 @ 80), (20), DFS - - country ES: DFS-ETSI -- (2400 - 2483.5 @ 40), (N/A, 100 mW) -- (5150 - 5250 @ 80), (N/A, 100 mW), NO-OUTDOOR -- (5250 - 5350 @ 80), (N/A, 100 mW), NO-OUTDOOR, DFS -- (5470 - 5725 @ 80), (N/A, 500 mW), DFS -+ (2400 - 2483.5 @ 40), (100 mW) -+ (5150 - 5250 @ 80), (100 mW), NO-OUTDOOR -+ (5250 - 5350 @ 80), (100 mW), NO-OUTDOOR -+ (5470 - 5725 @ 80), (500 mW), DFS - # 60 gHz band channels 1-4, ref: Etsi En 302 567 -- (57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR -+ (57240 - 65880 @ 2160), (40), NO-OUTDOOR - - country FI: DFS-ETSI -- (2402 - 2482 @ 40), (N/A, 20) -- (5170 - 5250 @ 80), (N/A, 20) -- (5250 - 5330 @ 80), (N/A, 20), DFS -- (5490 - 5710 @ 80), (N/A, 27), DFS -+ (2402 - 2482 @ 40), (20) -+ (5170 - 5250 @ 80), (20) -+ (5250 - 5330 @ 80), (20), DFS -+ (5490 - 5710 @ 80), (27), DFS - # 60 gHz band channels 1-4, ref: Etsi En 302 567 -- (57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR -+ (57240 - 65880 @ 2160), (40), NO-OUTDOOR - - country FR: DFS-ETSI -- (2402 - 2482 @ 40), (N/A, 20) -- (5170 - 5250 @ 80), (N/A, 20) -- (5250 - 5330 @ 80), (N/A, 20), DFS -- (5490 - 5710 @ 80), (N/A, 27), DFS -+ (2402 - 2482 @ 40), (20) -+ (5170 - 5250 @ 80), (20) -+ (5250 - 5330 @ 80), (20), DFS -+ (5490 - 5710 @ 80), (27), DFS - # 60 gHz band channels 1-4, ref: Etsi En 302 567 -- (57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR -+ (57240 - 65880 @ 2160), (40), NO-OUTDOOR - --country GE: -- (2402 - 2482 @ 40), (N/A, 20) -- (5170 - 5250 @ 40), (N/A, 18) -- (5250 - 5330 @ 40), (N/A, 18), DFS -+country GE: DFS-ETSI -+ (2402 - 2482 @ 40), (20) -+ (5170 - 5250 @ 80), (18) -+ (5250 - 5330 @ 80), (18), DFS - # 60 gHz band channels 1-4, ref: Etsi En 302 567 -- (57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR -+ (57240 - 65880 @ 2160), (40), NO-OUTDOOR - - country GB: DFS-ETSI -- (2402 - 2482 @ 40), (N/A, 20) -- (5170 - 5250 @ 80), (N/A, 20) -- (5250 - 5330 @ 80), (N/A, 20), DFS -- (5490 - 5710 @ 80), (N/A, 27), DFS -+ (2402 - 2482 @ 40), (20) -+ (5170 - 5250 @ 80), (20) -+ (5250 - 5330 @ 80), (20), DFS -+ (5490 - 5710 @ 80), (27), DFS - # 60 gHz band channels 1-4, ref: Etsi En 302 567 -- (57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR -+ (57240 - 65880 @ 2160), (40), NO-OUTDOOR - --country GD: -- (2402 - 2472 @ 40), (3, 27) -- (5170 - 5250 @ 40), (3, 17) -- (5250 - 5330 @ 40), (3, 20), DFS -- (5490 - 5710 @ 40), (3, 20), DFS -- (5735 - 5835 @ 40), (3, 30) -+country GD: DFS-FCC -+ (2402 - 2472 @ 40), (30) -+ (5170 - 5250 @ 80), (17) -+ (5250 - 5330 @ 80), (24), DFS -+ (5490 - 5730 @ 80), (24), DFS -+ (5735 - 5835 @ 80), (30) - - country GR: DFS-ETSI -- (2402 - 2482 @ 40), (N/A, 20) -- (5170 - 5250 @ 80), (N/A, 20) -- (5250 - 5330 @ 80), (N/A, 20), DFS -- (5490 - 5710 @ 80), (N/A, 27), DFS -+ (2402 - 2482 @ 40), (20) -+ (5170 - 5250 @ 80), (20) -+ (5250 - 5330 @ 80), (20), DFS -+ (5490 - 5710 @ 80), (27), DFS - # 60 gHz band channels 1-4, ref: Etsi En 302 567 -- (57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR -+ (57240 - 65880 @ 2160), (40), NO-OUTDOOR - - country GL: DFS-ETSI -- (2402 - 2482 @ 40), (N/A, 20) -- (5170 - 5250 @ 20), (N/A, 20) -- (5250 - 5330 @ 20), (N/A, 20), DFS -- (5490 - 5710 @ 20), (N/A, 27), DFS -- --country GT: -- (2402 - 2472 @ 40), (3, 27) -- (5170 - 5250 @ 40), (3, 17) -- (5250 - 5330 @ 40), (3, 23), DFS -- (5735 - 5835 @ 40), (3, 30) -- --country GU: -- (2402 - 2472 @ 40), (3, 27) -- (5170 - 5250 @ 80), (3, 17) -- (5250 - 5330 @ 80), (3, 24), DFS -- (5490 - 5710 @ 80), (3, 24), DFS -- (5735 - 5835 @ 80), (3, 30) -- --country HN: -- (2402 - 2482 @ 40), (N/A, 20) -- (5170 - 5250 @ 40), (3, 17) -- (5250 - 5330 @ 40), (3, 20), DFS -- (5490 - 5710 @ 40), (3, 20), DFS -- (5735 - 5835 @ 40), (3, 30) -+ (2402 - 2482 @ 40), (20) -+ (5170 - 5250 @ 80), (20) -+ (5250 - 5330 @ 80), (20), DFS -+ (5490 - 5710 @ 80), (27), DFS -+ -+country GT: DFS-FCC -+ (2402 - 2472 @ 40), (30) -+ (5170 - 5250 @ 80), (17) -+ (5250 - 5330 @ 80), (23), DFS -+ (5735 - 5835 @ 80), (30) -+ -+country GU: DFS-FCC -+ (2402 - 2472 @ 40), (30) -+ (5170 - 5250 @ 80), (17) -+ (5250 - 5330 @ 80), (24), DFS -+ (5490 - 5730 @ 80), (24), DFS -+ (5735 - 5835 @ 80), (30) -+ -+country HN: DFS-FCC -+ (2402 - 2482 @ 40), (20) -+ (5170 - 5250 @ 80), (17) -+ (5250 - 5330 @ 80), (24), DFS -+ (5490 - 5730 @ 80), (24), DFS -+ (5735 - 5835 @ 80), (30) - - country HK: -- (2402 - 2482 @ 40), (N/A, 20) -- (5170 - 5250 @ 80), (3, 17) -- (5250 - 5330 @ 80), (3, 24), DFS -- (5490 - 5710 @ 80), (3, 24), DFS -- (5735 - 5835 @ 80), (3, 30) -+ (2402 - 2482 @ 40), (20) -+ (5170 - 5250 @ 80), (17) -+ (5250 - 5330 @ 80), (24), DFS -+ (5490 - 5710 @ 80), (24), DFS -+ (5735 - 5835 @ 80), (30) - - country HR: DFS-ETSI -- (2402 - 2482 @ 40), (N/A, 20) -- (5170 - 5250 @ 40), (N/A, 20) -- (5250 - 5330 @ 40), (N/A, 20), DFS -- (5490 - 5710 @ 40), (N/A, 27), DFS -+ (2402 - 2482 @ 40), (20) -+ (5170 - 5250 @ 80), (20) -+ (5250 - 5330 @ 80), (20), DFS -+ (5490 - 5710 @ 80), (27), DFS - # 60 gHz band channels 1-4, ref: Etsi En 302 567 -- (57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR -+ (57240 - 65880 @ 2160), (40), NO-OUTDOOR - --country HT: -- (2402 - 2482 @ 40), (N/A, 20) -- (5170 - 5250 @ 40), (N/A, 20) -- (5250 - 5330 @ 40), (N/A, 20), DFS -- (5490 - 5710 @ 40), (N/A, 27), DFS -+country HT: DFS-ETSI -+ (2402 - 2482 @ 40), (20) -+ (5170 - 5250 @ 80), (20) -+ (5250 - 5330 @ 80), (20), DFS -+ (5490 - 5710 @ 80), (27), DFS - - country HU: DFS-ETSI -- (2402 - 2482 @ 40), (N/A, 20) -- (5170 - 5250 @ 40), (N/A, 20) -- (5250 - 5330 @ 40), (N/A, 20), DFS -- (5490 - 5710 @ 40), (N/A, 27), DFS -+ (2402 - 2482 @ 40), (20) -+ (5170 - 5250 @ 80), (20) -+ (5250 - 5330 @ 80), (20), DFS -+ (5490 - 5710 @ 80), (27), DFS - # 60 gHz band channels 1-4, ref: Etsi En 302 567 -- (57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR -+ (57240 - 65880 @ 2160), (40), NO-OUTDOOR - --country ID: -+country ID: DFS-JP - # ref: http://www.postel.go.id/content/ID/regulasi/standardisasi/kepdir/bwa%205,8%20ghz.pdf -- (2402 - 2482 @ 40), (N/A, 20) -- (5735 - 5815 @ 80), (N/A, 20) -+ (2402 - 2482 @ 40), (20) -+ (5735 - 5815 @ 80), (23) - - country IE: DFS-ETSI -- (2402 - 2482 @ 40), (N/A, 20) -- (5170 - 5250 @ 80), (N/A, 20) -- (5250 - 5330 @ 80), (N/A, 20), DFS -- (5490 - 5710 @ 80), (N/A, 27), DFS -+ (2402 - 2482 @ 40), (20) -+ (5170 - 5250 @ 80), (20) -+ (5250 - 5330 @ 80), (20), DFS -+ (5490 - 5710 @ 80), (27), DFS - # 60 gHz band channels 1-4, ref: Etsi En 302 567 -- (57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR -+ (57240 - 65880 @ 2160), (40), NO-OUTDOOR - --country IL: -- (2402 - 2482 @ 40), (N/A, 20) -- (5150 - 5250 @ 80), (N/A, 200 mW), NO-OUTDOOR -- (5250 - 5350 @ 80), (N/A, 200 mW), NO-OUTDOOR, DFS -+country IL: DFS-ETSI -+ (2402 - 2482 @ 40), (20) -+ (5150 - 5350 @ 80), (200 mW), NO-OUTDOOR - --country IN: -- (2402 - 2482 @ 40), (N/A, 20) -- (5170 - 5250 @ 40), (N/A, 20) -- (5250 - 5330 @ 40), (N/A, 20), DFS -- (5735 - 5835 @ 40), (N/A, 20) -+country IN: DFS-JP -+ (2402 - 2482 @ 40), (20) -+ (5170 - 5250 @ 80), (20) -+ (5250 - 5330 @ 80), (20), DFS -+ (5735 - 5835 @ 80), (20) - - country IS: DFS-ETSI -- (2402 - 2482 @ 40), (N/A, 20) -- (5170 - 5250 @ 40), (N/A, 20) -- (5250 - 5330 @ 40), (N/A, 20), DFS -- (5490 - 5710 @ 40), (N/A, 27), DFS -+ (2402 - 2482 @ 40), (20) -+ (5170 - 5250 @ 80), (20) -+ (5250 - 5330 @ 80), (20), DFS -+ (5490 - 5710 @ 80), (27), DFS - # 60 gHz band channels 1-4, ref: Etsi En 302 567 -- (57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR -+ (57240 - 65880 @ 2160), (40), NO-OUTDOOR - --country IR: -- (2402 - 2482 @ 40), (N/A, 20) -- (5735 - 5835 @ 40), (N/A, 30) -+country IR: DFS-JP -+ (2402 - 2482 @ 40), (20) -+ (5735 - 5835 @ 80), (30) - - country IT: DFS-ETSI -- (2402 - 2482 @ 40), (N/A, 20) -- (5170 - 5250 @ 80), (N/A, 20) -- (5250 - 5330 @ 80), (N/A, 20), DFS -- (5490 - 5710 @ 80), (N/A, 27), DFS -- # 60 gHz band channels 1-4, ref: Etsi En 302 567 -- (57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR -- --country JM: -- (2402 - 2482 @ 40), (N/A, 20) -- (5170 - 5250 @ 40), (3, 17) -- (5250 - 5330 @ 40), (3, 20), DFS -- (5490 - 5710 @ 40), (3, 20), DFS -- (5735 - 5835 @ 40), (3, 30) -- --country JP: -- (2402 - 2482 @ 40), (N/A, 20) -- (2474 - 2494 @ 20), (N/A, 20), NO-OFDM -- (4910 - 4990 @ 40), (N/A, 23) -- (5030 - 5090 @ 40), (N/A, 23) -- (5170 - 5250 @ 80), (N/A, 20) -- (5250 - 5330 @ 80), (N/A, 20), DFS -- (5490 - 5710 @ 160), (N/A, 23), DFS -- --country JO: -- (2402 - 2482 @ 40), (N/A, 20) -- (5170 - 5250 @ 40), (N/A, 18) -- --country KE: -- (2402 - 2482 @ 40), (N/A, 20) -- (5735 - 5835 @ 40), (N/A, 30) -- --country KH: -- (2402 - 2482 @ 40), (N/A, 20) -- (5170 - 5250 @ 40), (N/A, 20) -- (5250 - 5330 @ 40), (N/A, 20), DFS -- (5490 - 5710 @ 40), (N/A, 27), DFS -- --country KP: -- (2402 - 2482 @ 40), (N/A, 20) -- (5170 - 5330 @ 40), (3, 20) -- (5160 - 5250 @ 40), (3, 20), DFS -- (5490 - 5630 @ 40), (3, 30), DFS -- (5735 - 5815 @ 40), (3, 30) -- --country KR: -- (2402 - 2482 @ 20), (N/A, 20) -- (5170 - 5250 @ 80), (3, 20) -- (5250 - 5330 @ 80), (3, 20), DFS -- (5490 - 5630 @ 80), (3, 30), DFS -- (5735 - 5815 @ 80), (3, 30) -- --country KW: -- (2402 - 2482 @ 40), (N/A, 20) -- (5170 - 5250 @ 80), (N/A, 20) -- (5250 - 5330 @ 80), (N/A, 20), DFS -+ (2402 - 2482 @ 40), (20) -+ (5170 - 5250 @ 80), (20) -+ (5250 - 5330 @ 80), (20), DFS -+ (5490 - 5710 @ 80), (27), DFS -+ # 60 gHz band channels 1-4, ref: Etsi En 302 567 -+ (57240 - 65880 @ 2160), (40), NO-OUTDOOR -+ -+country JM: DFS-FCC -+ (2402 - 2482 @ 40), (20) -+ (5170 - 5250 @ 80), (17) -+ (5250 - 5330 @ 80), (24), DFS -+ (5490 - 5730 @ 80), (24), DFS -+ (5735 - 5835 @ 80), (30) -+ -+country JP: DFS-JP -+ (2402 - 2482 @ 40), (20) -+ (2474 - 2494 @ 20), (20), NO-OFDM -+ (4910 - 4990 @ 40), (23) -+ (5030 - 5090 @ 40), (23) -+ (5170 - 5250 @ 80), (20) -+ (5250 - 5330 @ 80), (20), DFS -+ (5490 - 5710 @ 160), (23), DFS -+ -+country JO: DFS-JP -+ (2402 - 2482 @ 40), (20) -+ (5170 - 5250 @ 80), (23) -+ (5735 - 5835 @ 80), (23) -+ -+country KE: DFS-JP -+ (2402 - 2482 @ 40), (20) -+ (5170 - 5250 @ 80), (23) -+ (5490 - 5570 @ 80), (30), DFS -+ (5735 - 5775 @ 40), (23) -+ -+country KH: DFS-ETSI -+ (2402 - 2482 @ 40), (20) -+ (5170 - 5250 @ 80), (20) -+ (5250 - 5330 @ 80), (20), DFS -+ (5490 - 5710 @ 80), (27), DFS -+ -+country KP: DFS-JP -+ (2402 - 2482 @ 40), (20) -+ (5170 - 5250 @ 80), (20) -+ (5250 - 5330 @ 80), (20), DFS -+ (5490 - 5630 @ 80), (30), DFS -+ (5735 - 5815 @ 80), (30) -+ -+country KR: DFS-JP -+ (2402 - 2482 @ 20), (20) -+ (2402 - 2482 @ 40), (20) -+ (5170 - 5250 @ 80), (20) -+ (5250 - 5330 @ 80), (20), DFS -+ (5490 - 5710 @ 80), (30), DFS -+ (5735 - 5815 @ 80), (30) -+ -+country KW: DFS-ETSI -+ (2402 - 2482 @ 40), (20) -+ (5170 - 5250 @ 80), (20) -+ (5250 - 5330 @ 80), (20), DFS - - country KZ: -- (2402 - 2482 @ 40), (N/A, 20) -+ (2402 - 2482 @ 40), (20) - --country LB: -- (2402 - 2482 @ 40), (N/A, 20) -- (5735 - 5835 @ 40), (N/A, 30) -+country LB: DFS-FCC -+ (2402 - 2482 @ 40), (20) -+ (5170 - 5250 @ 80), (17) -+ (5250 - 5330 @ 80), (24), DFS -+ (5490 - 5730 @ 80), (24), DFS -+ (5735 - 5835 @ 80), (30) - - country LI: DFS-ETSI -- (2402 - 2482 @ 40), (N/A, 20) -- (5170 - 5250 @ 40), (N/A, 20) -- (5250 - 5330 @ 40), (N/A, 20), DFS -- (5490 - 5710 @ 40), (N/A, 27), DFS -- --country LK: -- (2402 - 2482 @ 40), (N/A, 20) -- (5170 - 5250 @ 20), (3, 17) -- (5250 - 5330 @ 20), (3, 20), DFS -- (5490 - 5710 @ 20), (3, 20), DFS -- (5735 - 5835 @ 20), (3, 30) -+ (2402 - 2482 @ 40), (20) -+ (5170 - 5250 @ 80), (20) -+ (5250 - 5330 @ 80), (20), DFS -+ (5490 - 5710 @ 80), (27), DFS -+ -+country LK: DFS-FCC -+ (2402 - 2482 @ 40), (20) -+ (5170 - 5250 @ 80), (17) -+ (5250 - 5330 @ 80), (24), DFS -+ (5490 - 5730 @ 80), (24), DFS -+ (5735 - 5835 @ 80), (30) - - country LT: DFS-ETSI -- (2402 - 2482 @ 40), (N/A, 20) -- (5170 - 5250 @ 40), (N/A, 20) -- (5250 - 5330 @ 40), (N/A, 20), DFS -- (5490 - 5710 @ 40), (N/A, 27), DFS -+ (2402 - 2482 @ 40), (20) -+ (5170 - 5250 @ 80), (20) -+ (5250 - 5330 @ 80), (20), DFS -+ (5490 - 5710 @ 80), (27), DFS - # 60 gHz band channels 1-4, ref: Etsi En 302 567 -- (57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR -+ (57240 - 65880 @ 2160), (40), NO-OUTDOOR - - country LU: DFS-ETSI -- (2402 - 2482 @ 40), (N/A, 20) -- (5170 - 5250 @ 80), (N/A, 20) -- (5250 - 5330 @ 80), (N/A, 20), DFS -- (5490 - 5710 @ 80), (N/A, 27), DFS -+ (2402 - 2482 @ 40), (20) -+ (5170 - 5250 @ 80), (20) -+ (5250 - 5330 @ 80), (20), DFS -+ (5490 - 5710 @ 80), (27), DFS - # 60 gHz band channels 1-4, ref: Etsi En 302 567 -- (57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR -+ (57240 - 65880 @ 2160), (40), NO-OUTDOOR - - country LV: DFS-ETSI -- (2402 - 2482 @ 40), (N/A, 20) -- (5170 - 5250 @ 40), (N/A, 20) -- (5250 - 5330 @ 40), (N/A, 20), DFS -- (5490 - 5710 @ 40), (N/A, 27), DFS -+ (2402 - 2482 @ 40), (20) -+ (5170 - 5250 @ 80), (20) -+ (5250 - 5330 @ 80), (20), DFS -+ (5490 - 5710 @ 80), (27), DFS - # 60 gHz band channels 1-4, ref: Etsi En 302 567 -- (57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR -+ (57240 - 65880 @ 2160), (40), NO-OUTDOOR - - country MC: DFS-ETSI -- (2402 - 2482 @ 40), (N/A, 20) -- (5170 - 5250 @ 40), (N/A, 18) -- (5250 - 5330 @ 40), (N/A, 18), DFS -+ (2402 - 2482 @ 40), (20) -+ (5170 - 5250 @ 80), (20) -+ (5250 - 5330 @ 80), (20), DFS -+ (5490 - 5710 @ 80), (27), DFS - --country MA: -- (2402 - 2482 @ 40), (N/A, 20) -- (5170 - 5250 @ 80), (N/A, 23) -- (5735 - 5835 @ 80), (N/A, 23) -+country MA: DFS-ETSI -+ (2402 - 2482 @ 40), (20) -+ (5170 - 5250 @ 80), (20) -+ (5250 - 5330 @ 80), (20), DFS - - country MO: -- (2402 - 2482 @ 40), (N/A, 20) -- (5170 - 5250 @ 40), (3, 23) -- (5250 - 5330 @ 40), (3, 23), DFS -- (5735 - 5835 @ 40), (3, 30) -+ (2402 - 2482 @ 40), (20) -+ (5170 - 5250 @ 40), (23) -+ (5250 - 5330 @ 40), (23), DFS -+ (5735 - 5835 @ 40), (30) - - country MK: DFS-ETSI -- (2402 - 2482 @ 40), (N/A, 20) -- (5170 - 5250 @ 40), (N/A, 20) -- (5250 - 5330 @ 40), (N/A, 20), DFS -- (5490 - 5710 @ 40), (N/A, 27), DFS -+ (2402 - 2482 @ 40), (20) -+ (5170 - 5250 @ 80), (20) -+ (5250 - 5330 @ 80), (20), DFS -+ (5490 - 5710 @ 80), (27), DFS - # 60 gHz band channels 1-4, ref: Etsi En 302 567 -- (57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR -+ (57240 - 65880 @ 2160), (40), NO-OUTDOOR - - country MT: DFS-ETSI -- (2402 - 2482 @ 40), (N/A, 20) -- (5170 - 5250 @ 40), (N/A, 20) -- (5250 - 5330 @ 40), (N/A, 20), DFS -- (5490 - 5710 @ 40), (N/A, 27), DFS -- # 60 gHz band channels 1-4, ref: Etsi En 302 567 -- (57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR -- --country MY: -- (2402 - 2482 @ 40), (N/A, 20) -- (5170 - 5250 @ 80), (N/A, 17) -- (5250 - 5330 @ 80), (N/A, 23), DFS -- (5735 - 5835 @ 80), (N/A, 30) -- --country MX: -- (2402 - 2472 @ 40), (3, 27) -- (5170 - 5250 @ 80), (3, 17) -- (5250 - 5330 @ 80), (3, 24), DFS -- (5490 - 5710 @ 80), (3, 24), DFS -- (5735 - 5835 @ 80), (3, 30) -+ (2402 - 2482 @ 40), (20) -+ (5170 - 5250 @ 80), (20) -+ (5250 - 5330 @ 80), (20), DFS -+ (5490 - 5710 @ 80), (27), DFS -+ # 60 gHz band channels 1-4, ref: Etsi En 302 567 -+ (57240 - 65880 @ 2160), (40), NO-OUTDOOR -+ -+country MY: DFS-FCC -+ (2402 - 2482 @ 40), (20) -+ (5170 - 5250 @ 80), (17) -+ (5250 - 5330 @ 80), (23), DFS -+ (5735 - 5835 @ 80), (30) -+ -+country MX: DFS-FCC -+ (2402 - 2482 @ 40), (20) -+ (5170 - 5250 @ 80), (17) -+ (5250 - 5330 @ 80), (24), DFS -+ (5490 - 5730 @ 80), (24), DFS -+ (5735 - 5835 @ 80), (30) - - country NL: DFS-ETSI -- (2402 - 2482 @ 40), (N/A, 20) -- (5170 - 5250 @ 80), (N/A, 20), NO-OUTDOOR -- (5250 - 5330 @ 80), (N/A, 20), NO-OUTDOOR, DFS -- (5490 - 5710 @ 80), (N/A, 27), DFS -+ (2402 - 2482 @ 40), (20) -+ (5170 - 5330 @ 80), (20), NO-OUTDOOR -+ (5490 - 5710 @ 80), (27), DFS - # 60 gHz band channels 1-4, ref: Etsi En 302 567 -- (57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR -+ (57240 - 65880 @ 2160), (40), NO-OUTDOOR - - country NO: DFS-ETSI -- (2402 - 2482 @ 40), (N/A, 20) -- (5170 - 5250 @ 40), (N/A, 20) -- (5250 - 5330 @ 40), (N/A, 20), DFS -- (5490 - 5710 @ 40), (N/A, 27), DFS -- # 60 gHz band channels 1-4, ref: Etsi En 302 567 -- (57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR -- --country NP: -- (2402 - 2482 @ 40), (N/A, 20) -- (5735 - 5835 @ 40), (N/A, 30) -- --country NZ: -- (2402 - 2482 @ 40), (N/A, 30) -- (5170 - 5250 @ 80), (3, 17) -- (5250 - 5330 @ 80), (3, 24), DFS -- (5490 - 5710 @ 80), (3, 24), DFS -- (5735 - 5835 @ 80), (3, 30) -- --country OM: -- (2402 - 2482 @ 40), (N/A, 20) -- (5170 - 5250 @ 40), (3, 17) -- (5250 - 5330 @ 40), (3, 20), DFS -- (5490 - 5710 @ 40), (3, 20), DFS -- (5735 - 5835 @ 40), (3, 30) -- --country PA: -- (2402 - 2472 @ 40), (3, 27) -- (5170 - 5250 @ 40), (3, 17) -- (5250 - 5330 @ 40), (3, 23), DFS -- (5735 - 5835 @ 40), (3, 30) -- --country PE: -- (2402 - 2482 @ 40), (N/A, 20) -- (5170 - 5250 @ 80), (3, 17) -- (5250 - 5330 @ 80), (3, 24), DFS -- (5490 - 5710 @ 80), (3, 24), DFS -- (5735 - 5835 @ 80), (3, 30) -- --country PG: -- (2402 - 2482 @ 40), (N/A, 20) -- (5170 - 5250 @ 40), (3, 17) -- (5250 - 5330 @ 40), (3, 23), DFS -- (5735 - 5835 @ 40), (3, 30) -- --country PH: -- (2402 - 2482 @ 40), (N/A, 20) -- (5170 - 5250 @ 80), (3, 17) -- (5250 - 5330 @ 80), (3, 24), DFS -- (5490 - 5710 @ 80), (3, 24), DFS -- (5735 - 5835 @ 80), (3, 30) -- --country PK: -- (2402 - 2482 @ 40), (N/A, 20) -- (5735 - 5835 @ 40), (N/A, 30) -+ (2402 - 2482 @ 40), (20) -+ (5170 - 5250 @ 80), (20) -+ (5250 - 5330 @ 80), (20), DFS -+ (5490 - 5710 @ 80), (27), DFS -+ # 60 gHz band channels 1-4, ref: Etsi En 302 567 -+ (57240 - 65880 @ 2160), (40), NO-OUTDOOR -+ -+country NP: DFS-JP -+ (2402 - 2482 @ 40), (20) -+ (5170 - 5250 @ 80), (20) -+ (5250 - 5330 @ 80), (20), DFS -+ (5735 - 5835 @ 80), (20) -+ -+country NZ: DFS-FCC -+ (2402 - 2482 @ 40), (30) -+ (5170 - 5250 @ 80), (17) -+ (5250 - 5330 @ 80), (24), DFS -+ (5490 - 5730 @ 80), (24), DFS -+ (5735 - 5835 @ 80), (30) -+ -+country OM: DFS-ETSI -+ (2402 - 2482 @ 40), (20) -+ (5170 - 5250 @ 80), (20) -+ (5250 - 5330 @ 80), (20), DFS -+ (5490 - 5710 @ 80), (27), DFS -+ -+country PA: DFS-FCC -+ (2402 - 2472 @ 40), (30) -+ (5170 - 5250 @ 80), (17) -+ (5250 - 5330 @ 80), (23), DFS -+ (5735 - 5835 @ 80), (30) -+ -+country PE: DFS-FCC -+ (2402 - 2482 @ 40), (20) -+ (5170 - 5250 @ 80), (17) -+ (5250 - 5330 @ 80), (24), DFS -+ (5490 - 5730 @ 80), (24), DFS -+ (5735 - 5835 @ 80), (30) -+ -+country PG: DFS-FCC -+ (2402 - 2482 @ 40), (20) -+ (5170 - 5250 @ 80), (17) -+ (5250 - 5330 @ 80), (24), DFS -+ (5490 - 5730 @ 80), (24), DFS -+ (5735 - 5835 @ 80), (30) -+ -+country PH: DFS-FCC -+ (2402 - 2482 @ 40), (20) -+ (5170 - 5250 @ 80), (17) -+ (5250 - 5330 @ 80), (24), DFS -+ (5490 - 5730 @ 80), (24), DFS -+ (5735 - 5835 @ 80), (30) -+ -+country PK: DFS-JP -+ (2402 - 2482 @ 40), (20) -+ (5735 - 5835 @ 80), (30) - - country PL: DFS-ETSI -- (2402 - 2482 @ 40), (N/A, 20) -- (5170 - 5250 @ 80), (N/A, 20) -- (5250 - 5330 @ 80), (N/A, 20), DFS -- (5490 - 5710 @ 80), (N/A, 27), DFS -+ (2402 - 2482 @ 40), (20) -+ (5170 - 5250 @ 80), (20) -+ (5250 - 5330 @ 80), (20), DFS -+ (5490 - 5710 @ 80), (27), DFS - # 60 gHz band channels 1-4, ref: Etsi En 302 567 -- (57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR -+ (57240 - 65880 @ 2160), (40), NO-OUTDOOR - - country PT: DFS-ETSI -- (2402 - 2482 @ 40), (N/A, 20) -- (5170 - 5250 @ 80), (N/A, 20) -- (5250 - 5330 @ 80), (N/A, 20), DFS -- (5490 - 5710 @ 80), (N/A, 27), DFS -+ (2402 - 2482 @ 40), (20) -+ (5170 - 5250 @ 80), (20) -+ (5250 - 5330 @ 80), (20), DFS -+ (5490 - 5710 @ 80), (27), DFS - # 60 gHz band channels 1-4, ref: Etsi En 302 567 -- (57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR -+ (57240 - 65880 @ 2160), (40), NO-OUTDOOR - --country PR: -- (2402 - 2472 @ 40), (3, 27) -- (5170 - 5250 @ 80), (3, 17) -- (5250 - 5330 @ 80), (3, 24), DFS -- (5490 - 5710 @ 80), (3, 24), DFS -- (5735 - 5835 @ 80), (3, 30) -+country PR: DFS-FCC -+ (2402 - 2472 @ 40), (30) -+ (5170 - 5250 @ 80), (17) -+ (5250 - 5330 @ 80), (24), DFS -+ (5490 - 5730 @ 80), (24), DFS -+ (5735 - 5835 @ 80), (30) - --country QA: -- (2402 - 2482 @ 40), (N/A, 20) -- (5735 - 5835 @ 40), (N/A, 30) -+country QA: DFS-JP -+ (2402 - 2482 @ 40), (20) -+ (5735 - 5835 @ 80), (30) - - country RO: DFS-ETSI -- (2402 - 2482 @ 40), (N/A, 20) -- (5170 - 5250 @ 40), (N/A, 20) -- (5250 - 5330 @ 40), (N/A, 20), DFS -- (5490 - 5710 @ 40), (N/A, 27), DFS -+ (2402 - 2482 @ 40), (20) -+ (5170 - 5250 @ 80), (20) -+ (5250 - 5330 @ 80), (20), DFS -+ (5490 - 5710 @ 80), (27), DFS - # 60 gHz band channels 1-4, ref: Etsi En 302 567 -- (57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR -+ (57240 - 65880 @ 2160), (40), NO-OUTDOOR - - - # Source: - # http://www.ratel.rs/upload/documents/Plan_namene/Plan_namene-sl_glasnik.pdf --country RS: -- (2400 - 2483.5 @ 40), (N/A, 100 mW) -- (5150 - 5350 @ 40), (N/A, 200 mW), NO-OUTDOOR -- (5470 - 5725 @ 20), (3, 1000 mW), DFS -- # 60 gHz band channels 1-4, ref: Etsi En 302 567 -- (57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR -- --country RU: -- (2402 - 2482 @ 40), (N/A, 20) -- (5170 - 5330 @ 40), (N/A, 20) -- (5650 - 5710 @ 40), (N/A, 30) -- (5735 - 5835 @ 40), (N/A, 30) -- --country RW: -- (2402 - 2482 @ 40), (N/A, 20) -- (5735 - 5835 @ 40), (N/A, 30) -- --country SA: -- (2402 - 2482 @ 40), (N/A, 20) -- (5170 - 5250 @ 80), (3, 17) -- (5250 - 5330 @ 80), (3, 24), DFS -- (5490 - 5710 @ 80), (3, 24), DFS -- (5735 - 5835 @ 80), (3, 30) -+country RS: DFS-ETSI -+ (2400 - 2483.5 @ 40), (100 mW) -+ (5150 - 5350 @ 40), (200 mW), NO-OUTDOOR -+ (5470 - 5725 @ 20), (1000 mW), DFS -+ # 60 gHz band channels 1-4, ref: Etsi En 302 567 -+ (57240 - 65880 @ 2160), (40), NO-OUTDOOR -+ -+country RU: DFS-ETSI -+ (2402 - 2482 @ 40), (20) -+ (5170 - 5250 @ 80), (20) -+ (5250 - 5330 @ 80), (20), DFS -+ (5650 - 5730 @ 80), (30), DFS -+ (5735 - 5835 @ 80), (30) -+ -+country RW: DFS-FCC -+ (2402 - 2482 @ 40), (20) -+ (5170 - 5250 @ 80), (17) -+ (5250 - 5330 @ 80), (24), DFS -+ (5490 - 5730 @ 80), (24), DFS -+ (5735 - 5835 @ 80), (30) -+ -+country SA: DFS-ETSI -+ (2402 - 2482 @ 40), (20) -+ (5170 - 5250 @ 80), (20) -+ (5250 - 5330 @ 80), (20), DFS -+ (5490 - 5710 @ 80), (27), DFS - - country SE: DFS-ETSI -- (2402 - 2482 @ 40), (N/A, 20) -- (5170 - 5250 @ 80), (N/A, 20) -- (5250 - 5330 @ 80), (N/A, 20), DFS -- (5490 - 5710 @ 80), (N/A, 27), DFS -+ (2402 - 2482 @ 40), (20) -+ (5170 - 5250 @ 80), (20) -+ (5250 - 5330 @ 80), (20), DFS -+ (5490 - 5710 @ 80), (27), DFS - # 60 gHz band channels 1-4, ref: Etsi En 302 567 -- (57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR -+ (57240 - 65880 @ 2160), (40), NO-OUTDOOR - --country SG: -- (2402 - 2482 @ 40), (N/A, 20) -- (5170 - 5250 @ 80), (3, 17) -- (5250 - 5330 @ 80), (3, 24), DFS -- (5490 - 5710 @ 80), (3, 24), DFS -- (5735 - 5835 @ 80), (3, 30) -+country SG: DFS-FCC -+ (2402 - 2482 @ 40), (20) -+ (5170 - 5250 @ 80), (17) -+ (5250 - 5330 @ 80), (24), DFS -+ (5490 - 5730 @ 80), (24), DFS -+ (5735 - 5835 @ 80), (30) - - country SI: DFS-ETSI -- (2402 - 2482 @ 40), (N/A, 20) -- (5170 - 5250 @ 40), (N/A, 20) -- (5250 - 5330 @ 40), (N/A, 20), DFS -- (5490 - 5710 @ 40), (N/A, 27), DFS -+ (2402 - 2482 @ 40), (20) -+ (5170 - 5250 @ 80), (20) -+ (5250 - 5330 @ 80), (20), DFS -+ (5490 - 5710 @ 80), (27), DFS - # 60 gHz band channels 1-4, ref: Etsi En 302 567 -- (57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR -+ (57240 - 65880 @ 2160), (40), NO-OUTDOOR - - country SK: DFS-ETSI -- (2402 - 2482 @ 40), (N/A, 20) -- (5170 - 5250 @ 80), (N/A, 20) -- (5250 - 5330 @ 80), (N/A, 20), DFS -- (5490 - 5710 @ 80), (N/A, 27), DFS -+ (2402 - 2482 @ 40), (20) -+ (5170 - 5250 @ 80), (20) -+ (5250 - 5330 @ 80), (20), DFS -+ (5490 - 5710 @ 80), (27), DFS - # 60 gHz band channels 1-4, ref: Etsi En 302 567 -- (57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR -+ (57240 - 65880 @ 2160), (40), NO-OUTDOOR - --country SV: -- (2402 - 2482 @ 40), (N/A, 20) -- (5170 - 5250 @ 20), (3, 17) -- (5250 - 5330 @ 20), (3, 23), DFS -- (5735 - 5835 @ 20), (3, 30) -+country SV: DFS-FCC -+ (2402 - 2482 @ 40), (20) -+ (5170 - 5250 @ 80), (17) -+ (5250 - 5330 @ 80), (23), DFS -+ (5735 - 5835 @ 80), (30) - - country SY: -- (2402 - 2482 @ 40), (N/A, 20) -- --country TW: -- (2402 - 2472 @ 40), (3, 27) -- (5270 - 5330 @ 40), (3, 17), DFS -- (5490 - 5710 @ 80), (3, 30), DFS -- (5735 - 5815 @ 80), (3, 30) -- --country TH: -- (2402 - 2482 @ 40), (N/A, 20) -- (5170 - 5250 @ 80), (3, 17) -- (5250 - 5330 @ 80), (3, 24), DFS -- (5490 - 5710 @ 80), (3, 24), DFS -- (5735 - 5835 @ 80), (3, 30) -- --country TT: -- (2402 - 2482 @ 40), (N/A, 20) -- (5170 - 5250 @ 40), (3, 17) -- (5250 - 5330 @ 40), (3, 20), DFS -- (5490 - 5710 @ 40), (3, 20), DFS -- (5735 - 5835 @ 40), (3, 30) -- --country TN: -- (2402 - 2482 @ 40), (N/A, 20) -- (5170 - 5250 @ 20), (N/A, 20) -- (5250 - 5330 @ 20), (N/A, 20), DFS -+ (2402 - 2482 @ 40), (20) -+ -+country TW: DFS-JP -+ (2402 - 2472 @ 40), (30) -+ (5270 - 5330 @ 40), (17), DFS -+ (5490 - 5590 @ 80), (30), DFS -+ (5650 - 5710 @ 40), (30), DFS -+ (5735 - 5835 @ 80), (30) -+ -+country TH: DFS-FCC -+ (2402 - 2482 @ 40), (20) -+ (5170 - 5250 @ 80), (17) -+ (5250 - 5330 @ 80), (24), DFS -+ (5490 - 5730 @ 80), (24), DFS -+ (5735 - 5835 @ 80), (30) -+ -+country TT: DFS-FCC -+ (2402 - 2482 @ 40), (20) -+ (5170 - 5250 @ 80), (17) -+ (5250 - 5330 @ 80), (24), DFS -+ (5490 - 5730 @ 80), (24), DFS -+ (5735 - 5835 @ 80), (30) -+ -+country TN: DFS-ETSI -+ (2402 - 2482 @ 40), (20) -+ (5170 - 5250 @ 80), (20) -+ (5250 - 5330 @ 80), (20), DFS - - country TR: DFS-ETSI -- (2402 - 2482 @ 40), (N/A, 20) -- (5170 - 5250 @ 80), (N/A, 20) -- (5250 - 5330 @ 80), (N/A, 20), DFS -- (5490 - 5710 @ 80), (N/A, 27), DFS -+ (2402 - 2482 @ 40), (20) -+ (5170 - 5250 @ 80), (20) -+ (5250 - 5330 @ 80), (20), DFS -+ (5490 - 5710 @ 80), (27), DFS - # 60 gHz band channels 1-4, ref: Etsi En 302 567 -- (57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR -+ (57240 - 65880 @ 2160), (40), NO-OUTDOOR - - # Source: - # #914 / 06 Sep 2007: http://www.ucrf.gov.ua/uk/doc/nkrz/1196068874 -@@ -765,59 +783,63 @@ country TR: DFS-ETSI - # Listed 5GHz range is a lowest common denominator for all related - # rules in the referenced laws. Such a range is used because of - # disputable definitions there. --country UA: -- (2400 - 2483.5 @ 40), (N/A, 20), NO-OUTDOOR -- (5150 - 5350 @ 40), (N/A, 20), NO-OUTDOOR -+country UA: DFS-ETSI -+ (2400 - 2483.5 @ 40), (20), NO-OUTDOOR -+ (5150 - 5350 @ 40), (20), NO-OUTDOOR -+ (5490 - 5670 @ 80), (20), DFS -+ (5735 - 5835 @ 80), (20) - # 60 gHz band channels 1-4, ref: Etsi En 302 567 -- (57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR -+ (57240 - 65880 @ 2160), (40), NO-OUTDOOR - - country US: DFS-FCC -- (2402 - 2472 @ 40), (3, 27) -- (5170 - 5250 @ 80), (3, 17) -- (5250 - 5330 @ 80), (3, 24), DFS -- (5490 - 5600 @ 80), (3, 24), DFS -- (5650 - 5710 @ 40), (3, 24), DFS -- (5735 - 5835 @ 80), (3, 30) -+ (2402 - 2472 @ 40), (30) -+ (5170 - 5250 @ 80), (17) -+ (5250 - 5330 @ 80), (23), DFS -+ (5735 - 5835 @ 80), (30) - # 60g band - # reference: http://cfr.regstoday.com/47cfr15.aspx#47_CFR_15p255 - # channels 1,2,3, EIRP=40dBm(43dBm peak) -- (57240 - 63720 @ 2160), (N/A, 40) -- --country UY: -- (2402 - 2482 @ 40), (N/A, 20) -- (5170 - 5250 @ 40), (3, 17) -- (5250 - 5330 @ 40), (3, 20), DFS -- (5490 - 5710 @ 40), (3, 20), DFS -- (5735 - 5835 @ 40), (3, 30) -- --country UZ: -- (2402 - 2472 @ 40), (3, 27) -- (5170 - 5250 @ 40), (3, 17) -- (5250 - 5330 @ 40), (3, 20), DFS -- (5490 - 5710 @ 40), (3, 20), DFS -- (5735 - 5835 @ 40), (3, 30) -- --country VE: -- (2402 - 2482 @ 40), (N/A, 20) -- (5735 - 5815 @ 40), (N/A, 23) -- --country VN: -- (2402 - 2482 @ 40), (N/A, 20) -- (5170 - 5250 @ 80), (3, 17) -- (5250 - 5330 @ 80), (3, 24), DFS -- (5490 - 5710 @ 80), (3, 24), DFS -- (5735 - 5835 @ 80), (3, 30) -+ (57240 - 63720 @ 2160), (40) -+ -+country UY: DFS-FCC -+ (2402 - 2482 @ 40), (20) -+ (5170 - 5250 @ 80), (17) -+ (5250 - 5330 @ 80), (24), DFS -+ (5490 - 5730 @ 80), (24), DFS -+ (5735 - 5835 @ 80), (30) -+ -+country UZ: DFS-FCC -+ (2402 - 2472 @ 40), (30) -+ (5170 - 5250 @ 80), (17) -+ (5250 - 5330 @ 80), (24), DFS -+ (5490 - 5730 @ 80), (24), DFS -+ (5735 - 5835 @ 80), (30) -+ -+country VE: DFS-FCC -+ (2402 - 2482 @ 40), (20) -+ (5170 - 5250 @ 80), (17) -+ (5250 - 5330 @ 80), (23), DFS -+ (5735 - 5835 @ 80), (30) -+ -+country VN: DFS-FCC -+ (2402 - 2482 @ 40), (20) -+ (5170 - 5250 @ 80), (17) -+ (5250 - 5330 @ 80), (24), DFS -+ (5490 - 5730 @ 80), (24), DFS -+ (5735 - 5835 @ 80), (30) - - country YE: -- (2402 - 2482 @ 40), (N/A, 20) -- --country ZA: -- (2402 - 2482 @ 40), (N/A, 20) -- (5170 - 5250 @ 80), (3, 17) -- (5250 - 5330 @ 80), (3, 24), DFS -- (5490 - 5710 @ 80), (3, 24), DFS -- (5735 - 5835 @ 80), (3, 30) -- --country ZW: -- (2402 - 2482 @ 40), (N/A, 20) -+ (2402 - 2482 @ 40), (20) -+ -+country ZA: DFS-ETSI -+ (2402 - 2482 @ 40), (20) -+ (5170 - 5250 @ 80), (20) -+ (5250 - 5330 @ 80), (20), DFS -+ (5490 - 5710 @ 80), (27), DFS -+ -+country ZW: DFS-ETSI -+ (2402 - 2482 @ 40), (20) -+ (5170 - 5250 @ 80), (20) -+ (5250 - 5330 @ 80), (20), DFS -+ (5490 - 5710 @ 80), (27), DFS - -diff --git a/package/mac80211/patches/001-fix_build.patch b/package/mac80211/patches/001-fix_build.patch -index 26b327a..99ef50e 100644 ---- a/package/mac80211/patches/001-fix_build.patch -+++ b/package/mac80211/patches/001-fix_build.patch -@@ -131,7 +131,7 @@ - .PHONY: defconfig-help - --- a/Makefile.real - +++ b/Makefile.real --@@ -54,7 +54,7 @@ defconfig-%:: -+@@ -59,7 +59,7 @@ defconfig-%:: - - backport-include/backport/autoconf.h: .config Kconfig.versions Kconfig.kernel - @$(MAKE) oldconfig -@@ -140,7 +140,7 @@ - @grep -f .local-symbols .config | ( \ - echo "#ifndef COMPAT_AUTOCONF_INCLUDED" ;\ - echo "#define COMPAT_AUTOCONF_INCLUDED" ;\ --@@ -75,7 +75,12 @@ backport-include/backport/autoconf.h: .c -+@@ -80,7 +80,12 @@ backport-include/backport/autoconf.h: .c - esac ;\ - done ;\ - echo "#endif /* COMPAT_AUTOCONF_INCLUDED */" ;\ -diff --git a/package/mac80211/patches/003-remove_bogus_modparams.patch b/package/mac80211/patches/003-remove_bogus_modparams.patch -index c969b19..ffb730b 100644 ---- a/package/mac80211/patches/003-remove_bogus_modparams.patch -+++ b/package/mac80211/patches/003-remove_bogus_modparams.patch -@@ -1,6 +1,6 @@ - --- a/compat/main.c - +++ b/compat/main.c --@@ -21,31 +21,6 @@ MODULE_LICENSE("GPL"); -+@@ -20,31 +20,6 @@ MODULE_LICENSE("GPL"); - #error "You need a BACKPORTS_VERSION" - #endif - -diff --git a/package/mac80211/patches/004-backports-add-led_trigger_blink-_oneshot.patch b/package/mac80211/patches/004-backports-add-led_trigger_blink-_oneshot.patch -index 584fb05..8d97224 100644 ---- a/package/mac80211/patches/004-backports-add-led_trigger_blink-_oneshot.patch -+++ b/package/mac80211/patches/004-backports-add-led_trigger_blink-_oneshot.patch -@@ -18,8 +18,8 @@ Signed-off-by: Hauke Mehrtens - - --- a/backport-include/backport/leds-disabled.h - +++ b/backport-include/backport/leds-disabled.h --@@ -163,6 +163,19 @@ static inline void led_trigger_event(str -- enum led_brightness event) -+@@ -176,6 +176,19 @@ static inline void led_trigger_blink_one -+ int invert) - { - } - + -diff --git a/package/mac80211/patches/005-make-genregdb.awk-skip-antenna-gain.patch b/package/mac80211/patches/005-make-genregdb.awk-skip-antenna-gain.patch -new file mode 100644 -index 0000000..55bffbc ---- /dev/null -+++ b/package/mac80211/patches/005-make-genregdb.awk-skip-antenna-gain.patch -@@ -0,0 +1,44 @@ -+From: Luis R. Rodriguez -+Date: Wed, 23 Oct 2013 14:55:36 -0400 -+Subject: [RFC] cfg80211: make genregdb.awk skip antenna gain -+ -+Now that wireless-regdb doesn't include -+antenna gain lets skip parsing it completely -+for when CONFIG_CFG80211_INTERNAL_REGDB is -+enabled. -+ -+Signed-off-by: Luis R. Rodriguez -+--- -+ net/wireless/genregdb.awk | 11 ++++------- -+ 1 file changed, 4 insertions(+), 7 deletions(-) -+ mode change 100644 => 100755 net/wireless/genregdb.awk -+ -+--- a/net/wireless/genregdb.awk -++++ b/net/wireless/genregdb.awk -+@@ -56,14 +56,11 @@ function parse_reg_rule() -+ end = $3 -+ bw = $5 -+ sub(/\),/, "", bw) -+- gain = $6 -+- sub(/\(/, "", gain) -+- sub(/,/, "", gain) -+- power = $7 -+- sub(/\)/, "", power) -++ power = $6 -++ sub(/\(/, "", power) -+ sub(/,/, "", power) -+ # power might be in mW... -+- units = $8 -++ units = $7 -+ sub(/\)/, "", units) -+ sub(/,/, "", units) -+ dfs_cac = $9 -+@@ -86,7 +83,7 @@ function parse_reg_rule() -+ sub(/\(/, "", dfs_cac) -+ sub(/\)/, "", dfs_cac) -+ flagstr = "" -+- for (i=8; i<=NF; i++) -++ for (i=7; i<=NF; i++) -+ flagstr = flagstr $i -+ split(flagstr, flagarray, ",") -+ flags = "" -diff --git a/package/mac80211/patches/007-select_queue.patch b/package/mac80211/patches/007-select_queue.patch -new file mode 100644 -index 0000000..0a1d292 ---- /dev/null -+++ b/package/mac80211/patches/007-select_queue.patch -@@ -0,0 +1,11 @@ -+--- a/drivers/net/wireless/mwifiex/main.c -++++ b/drivers/net/wireless/mwifiex/main.c -+@@ -745,7 +745,7 @@ static struct net_device_stats *mwifiex_ -+ return &priv->stats; -+ } -+ -+-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0) -++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0) -+ static u16 -+ mwifiex_netdev_select_wmm_queue(struct net_device *dev, struct sk_buff *skb, -+ void *accel_priv, select_queue_fallback_t fallback) -diff --git a/package/mac80211/patches/020-disable_tty_set_termios.patch b/package/mac80211/patches/020-disable_tty_set_termios.patch -deleted file mode 100644 -index e6d4ff6..0000000 ---- a/package/mac80211/patches/020-disable_tty_set_termios.patch -+++ /dev/null -@@ -1,16 +0,0 @@ ----- a/compat/compat-2.6.39.c --+++ b/compat/compat-2.6.39.c --@@ -13,6 +13,7 @@ -- #include -- #include -- --+#ifdef CONFIG_COMPAT_BLUETOOTH -- #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)) -- #ifdef CONFIG_TTY -- /* --@@ -114,4 +115,4 @@ int tty_set_termios(struct tty_struct *t -- EXPORT_SYMBOL_GPL(tty_set_termios); -- #endif /* CONFIG_TTY */ -- #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)) */ --- --+#endif -diff --git a/package/mac80211/patches/050-lib80211_option.patch b/package/mac80211/patches/050-lib80211_option.patch -index 5372114..168871a 100644 ---- a/package/mac80211/patches/050-lib80211_option.patch -+++ b/package/mac80211/patches/050-lib80211_option.patch -@@ -1,6 +1,6 @@ - --- a/net/wireless/Kconfig - +++ b/net/wireless/Kconfig --@@ -123,7 +123,7 @@ config CFG80211_WEXT -+@@ -160,7 +160,7 @@ config CFG80211_WEXT - extensions with cfg80211-based drivers. - - config LIB80211 -@@ -9,7 +9,7 @@ - depends on m - default n - help --@@ -133,15 +133,15 @@ config LIB80211 -+@@ -170,15 +170,15 @@ config LIB80211 - Drivers should select this themselves if needed. - - config LIB80211_CRYPT_WEP -diff --git a/package/mac80211/patches/060-no_local_ssb_bcma.patch b/package/mac80211/patches/060-no_local_ssb_bcma.patch -index f4b9470..93197ae 100644 ---- a/package/mac80211/patches/060-no_local_ssb_bcma.patch -+++ b/package/mac80211/patches/060-no_local_ssb_bcma.patch -@@ -1,6 +1,6 @@ - --- a/.local-symbols - +++ b/.local-symbols --@@ -379,42 +379,6 @@ USB_CDC_PHONET= -+@@ -403,42 +403,6 @@ USB_CDC_PHONET= - USB_IPHETH= - USB_SIERRA_NET= - USB_VL600= -@@ -68,7 +68,7 @@ - obj-$(CPTCFG_NFC) += net/nfc/ - --- a/drivers/net/wireless/b43/main.c - +++ b/drivers/net/wireless/b43/main.c --@@ -2734,7 +2734,7 @@ static struct ssb_device *b43_ssb_gpio_d -+@@ -2733,7 +2733,7 @@ static struct ssb_device *b43_ssb_gpio_d - { - struct ssb_bus *bus = dev->dev->sdev->bus; - -@@ -77,12 +77,12 @@ - return (bus->chipco.dev ? bus->chipco.dev : bus->pcicore.dev); - #else - return bus->chipco.dev; --@@ -4751,7 +4751,7 @@ static int b43_wireless_core_init(struct -+@@ -4698,7 +4698,7 @@ static int b43_wireless_core_init(struct - } - if (sprom->boardflags_lo & B43_BFL_XTAL_NOSLOW) - hf |= B43_HF_DSCRQ; /* Disable slowclock requests from ucode. */ ---#ifdef CPTCFG_SSB_DRIVER_PCICORE --+#ifdef CONFIG_SSB_DRIVER_PCICORE -+-#if defined(CPTCFG_B43_SSB) && defined(CPTCFG_SSB_DRIVER_PCICORE) -++#if defined(CPTCFG_B43_SSB) && defined(CONFIG_SSB_DRIVER_PCICORE) - if (dev->dev->bus_type == B43_BUS_SSB && - dev->dev->sdev->bus->bustype == SSB_BUSTYPE_PCI && - dev->dev->sdev->bus->pcicore.dev->id.revision <= 10) -diff --git a/package/mac80211/patches/070-add-missing-header.patch b/package/mac80211/patches/070-add-missing-header.patch -new file mode 100644 -index 0000000..e3ec780 ---- /dev/null -+++ b/package/mac80211/patches/070-add-missing-header.patch -@@ -0,0 +1,10 @@ -+--- a/compat/backport-3.15.c -++++ b/compat/backport-3.15.c -+@@ -12,6 +12,7 @@ -+ #include -+ #include -+ #include -++#include -+ #include -+ -+ #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)) -diff --git a/package/mac80211/patches/100-revert_aes_ccm_port.patch b/package/mac80211/patches/100-revert_aes_ccm_port.patch -index 4654bc8..640d34e 100644 ---- a/package/mac80211/patches/100-revert_aes_ccm_port.patch -+++ b/package/mac80211/patches/100-revert_aes_ccm_port.patch -@@ -4,7 +4,7 @@ - depends on CRYPTO - depends on CRYPTO_ARC4 - depends on CRYPTO_AES --- depends on CRYPTO_CCM -+- select BACKPORT_CRYPTO_CCM - depends on CRC32 - select BACKPORT_AVERAGE - ---help--- -@@ -19,35 +19,17 @@ - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. --@@ -19,75 +17,134 @@ -+@@ -19,76 +17,134 @@ - #include "key.h" - #include "aes_ccm.h" - - -void ieee80211_aes_ccm_encrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad, - - u8 *data, size_t data_len, u8 *mic) - +static void aes_ccm_prepare(struct crypto_cipher *tfm, u8 *scratch, u8 *a) -- { --- struct scatterlist assoc, pt, ct[2]; --- struct { --- struct aead_request req; --- u8 priv[crypto_aead_reqsize(tfm)]; --- } aead_req; --- --- memset(&aead_req, 0, sizeof(aead_req)); --- --- sg_init_one(&pt, data, data_len); --- sg_init_one(&assoc, &aad[2], be16_to_cpup((__be16 *)aad)); --- sg_init_table(ct, 2); --- sg_set_buf(&ct[0], data, data_len); --- sg_set_buf(&ct[1], mic, IEEE80211_CCMP_MIC_LEN); --- --- aead_request_set_tfm(&aead_req.req, tfm); --- aead_request_set_assoc(&aead_req.req, &assoc, assoc.length); --- aead_request_set_crypt(&aead_req.req, &pt, ct, data_len, b_0); -++{ - + int i; - + u8 *b_0, *aad, *b, *s_0; -- --- crypto_aead_encrypt(&aead_req.req); -++ - + b_0 = scratch + 3 * AES_BLOCK_SIZE; - + aad = scratch + 4 * AES_BLOCK_SIZE; - + b = scratch; -@@ -73,22 +55,23 @@ - + b_0[14] = 0; - + b_0[15] = 0; - + crypto_cipher_encrypt_one(tfm, s_0, b_0); -- } -- ---int ieee80211_aes_ccm_decrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad, --- u8 *data, size_t data_len, u8 *mic) -++} -++ - + - +void ieee80211_aes_ccm_encrypt(struct crypto_cipher *tfm, u8 *scratch, - + u8 *data, size_t data_len, - + u8 *cdata, u8 *mic) - { - - struct scatterlist assoc, pt, ct[2]; --- struct { --- struct aead_request req; --- u8 priv[crypto_aead_reqsize(tfm)]; --- } aead_req; -++ int i, j, last_len, num_blocks; -++ u8 *pos, *cpos, *b, *s_0, *e, *b_0; -+ -+- char aead_req_data[sizeof(struct aead_request) + -+- crypto_aead_reqsize(tfm)] -+- __aligned(__alignof__(struct aead_request)); -+- struct aead_request *aead_req = (void *) aead_req_data; - - --- memset(&aead_req, 0, sizeof(aead_req)); -+- memset(aead_req, 0, sizeof(aead_req_data)); - - - - sg_init_one(&pt, data, data_len); - - sg_init_one(&assoc, &aad[2], be16_to_cpup((__be16 *)aad)); -@@ -96,13 +79,9 @@ - - sg_set_buf(&ct[0], data, data_len); - - sg_set_buf(&ct[1], mic, IEEE80211_CCMP_MIC_LEN); - - --- aead_request_set_tfm(&aead_req.req, tfm); --- aead_request_set_assoc(&aead_req.req, &assoc, assoc.length); --- aead_request_set_crypt(&aead_req.req, ct, &pt, --- data_len + IEEE80211_CCMP_MIC_LEN, b_0); --+ int i, j, last_len, num_blocks; --+ u8 *pos, *cpos, *b, *s_0, *e, *b_0; --+ -+- aead_request_set_tfm(aead_req, tfm); -+- aead_request_set_assoc(aead_req, &assoc, assoc.length); -+- aead_request_set_crypt(aead_req, &pt, ct, data_len, b_0); - + b = scratch; - + s_0 = scratch + AES_BLOCK_SIZE; - + e = scratch + 2 * AES_BLOCK_SIZE; -@@ -131,30 +110,38 @@ - + *cpos++ = *pos++ ^ e[i]; - + } - --- return crypto_aead_decrypt(&aead_req.req); -+- crypto_aead_encrypt(aead_req); - + for (i = 0; i < IEEE80211_CCMP_MIC_LEN; i++) - + mic[i] = b[i] ^ s_0[i]; - } - ---struct crypto_aead *ieee80211_aes_key_setup_encrypt(const u8 key[]) -+-int ieee80211_aes_ccm_decrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad, -+- u8 *data, size_t data_len, u8 *mic) - + - +int ieee80211_aes_ccm_decrypt(struct crypto_cipher *tfm, u8 *scratch, - + u8 *cdata, size_t data_len, u8 *mic, u8 *data) - { --- struct crypto_aead *tfm; --- int err; -+- struct scatterlist assoc, pt, ct[2]; -+- char aead_req_data[sizeof(struct aead_request) + -+- crypto_aead_reqsize(tfm)] -+- __aligned(__alignof__(struct aead_request)); -+- struct aead_request *aead_req = (void *) aead_req_data; -+- -+- memset(aead_req, 0, sizeof(aead_req_data)); -+- -+- sg_init_one(&pt, data, data_len); -+- sg_init_one(&assoc, &aad[2], be16_to_cpup((__be16 *)aad)); -+- sg_init_table(ct, 2); -+- sg_set_buf(&ct[0], data, data_len); -+- sg_set_buf(&ct[1], mic, IEEE80211_CCMP_MIC_LEN); -+- -+- aead_request_set_tfm(aead_req, tfm); -+- aead_request_set_assoc(aead_req, &assoc, assoc.length); -+- aead_request_set_crypt(aead_req, ct, &pt, -+- data_len + IEEE80211_CCMP_MIC_LEN, b_0); - + int i, j, last_len, num_blocks; - + u8 *pos, *cpos, *b, *s_0, *a, *b_0; -- --- tfm = crypto_alloc_aead("ccm(aes)", 0, CRYPTO_ALG_ASYNC); --- if (IS_ERR(tfm)) --- return tfm; --- --- err = crypto_aead_setkey(tfm, key, WLAN_KEY_LEN_CCMP); --- if (!err) --- err = crypto_aead_setauthsize(tfm, IEEE80211_CCMP_MIC_LEN); --- if (!err) --- return tfm; -++ - + b = scratch; - + s_0 = scratch + AES_BLOCK_SIZE; - + a = scratch + 2 * AES_BLOCK_SIZE; -@@ -187,24 +174,37 @@ - + return -1; - + } - --- crypto_free_aead(tfm); --- return ERR_PTR(err); -+- return crypto_aead_decrypt(aead_req); - + return 0; - } - ---void ieee80211_aes_key_free(struct crypto_aead *tfm) -+-struct crypto_aead *ieee80211_aes_key_setup_encrypt(const u8 key[]) - + - +struct crypto_cipher *ieee80211_aes_key_setup_encrypt(const u8 key[]) --+{ -+ { -+- struct crypto_aead *tfm; -+- int err; - + struct crypto_cipher *tfm; --+ -+ -+- tfm = crypto_alloc_aead("ccm(aes)", 0, CRYPTO_ALG_ASYNC); -+- if (IS_ERR(tfm)) -+- return tfm; -+- -+- err = crypto_aead_setkey(tfm, key, WLAN_KEY_LEN_CCMP); -+- if (!err) -+- err = crypto_aead_setauthsize(tfm, IEEE80211_CCMP_MIC_LEN); -+- if (!err) -+- return tfm; - + tfm = crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC); - + if (!IS_ERR(tfm)) - + crypto_cipher_setkey(tfm, key, WLAN_KEY_LEN_CCMP); --+ -+ -+- crypto_free_aead(tfm); -+- return ERR_PTR(err); - + return tfm; --+} --+ -+ } -+ -+-void ieee80211_aes_key_free(struct crypto_aead *tfm) - + - +void ieee80211_aes_key_free(struct crypto_cipher *tfm) - { -@@ -246,13 +246,13 @@ - struct { - --- a/net/mac80211/wpa.c - +++ b/net/mac80211/wpa.c --@@ -301,16 +301,22 @@ ieee80211_crypto_tkip_decrypt(struct iee -+@@ -301,15 +301,22 @@ ieee80211_crypto_tkip_decrypt(struct iee - } - - ---static void ccmp_special_blocks(struct sk_buff *skb, u8 *pn, u8 *b_0, u8 *aad, -+-static void ccmp_special_blocks(struct sk_buff *skb, u8 *pn, u8 *b_0, u8 *aad) - +static void ccmp_special_blocks(struct sk_buff *skb, u8 *pn, u8 *scratch, -- int encrypted) -++ int encrypted) - { - __le16 mask_fc; - int a4_included, mgmt; -@@ -271,7 +271,7 @@ - /* - * Mask FC: zero subtype b4 b5 b6 (if not mgmt) - * Retry, PwrMgt, MoreData; set Protected --@@ -332,21 +338,20 @@ static void ccmp_special_blocks(struct s -+@@ -331,21 +338,20 @@ static void ccmp_special_blocks(struct s - else - qos_tid = 0; - -@@ -300,7 +300,7 @@ - - /* AAD (extra authenticate-only data) / masked 802.11 header - * FC | A1 | A2 | A3 | SC | [A4] | [QC] */ --@@ -402,8 +407,7 @@ static int ccmp_encrypt_skb(struct ieee8 -+@@ -401,8 +407,7 @@ static int ccmp_encrypt_skb(struct ieee8 - u8 *pos; - u8 pn[6]; - u64 pn64; -@@ -310,11 +310,11 @@ - - if (info->control.hw_key && - !(info->control.hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_IV) && --@@ -456,9 +460,9 @@ static int ccmp_encrypt_skb(struct ieee8 -+@@ -458,9 +463,9 @@ static int ccmp_encrypt_skb(struct ieee8 - return 0; - - pos += IEEE80211_CCMP_HDR_LEN; --- ccmp_special_blocks(skb, pn, b_0, aad, 0); -+- ccmp_special_blocks(skb, pn, b_0, aad); - - ieee80211_aes_ccm_encrypt(key->u.ccmp.tfm, b_0, aad, pos, len, - - skb_put(skb, IEEE80211_CCMP_MIC_LEN)); - + ccmp_special_blocks(skb, pn, scratch, 0); -@@ -323,7 +323,7 @@ - - return 0; - } --@@ -521,16 +525,16 @@ ieee80211_crypto_ccmp_decrypt(struct iee -+@@ -523,16 +528,16 @@ ieee80211_crypto_ccmp_decrypt(struct iee - } - - if (!(status->flag & RX_FLAG_DECRYPTED)) { -@@ -331,7 +331,7 @@ - - u8 b_0[AES_BLOCK_SIZE]; - + u8 scratch[6 * AES_BLOCK_SIZE]; - /* hardware didn't decrypt/verify MIC */ --- ccmp_special_blocks(skb, pn, b_0, aad, 1); -+- ccmp_special_blocks(skb, pn, b_0, aad); - + ccmp_special_blocks(skb, pn, scratch, 1); - - if (ieee80211_aes_ccm_decrypt( -diff --git a/package/mac80211/patches/150-disable_addr_notifier.patch b/package/mac80211/patches/150-disable_addr_notifier.patch -index 7b50154..6a7f5c1 100644 ---- a/package/mac80211/patches/150-disable_addr_notifier.patch -+++ b/package/mac80211/patches/150-disable_addr_notifier.patch -@@ -1,6 +1,6 @@ - --- a/net/mac80211/main.c - +++ b/net/mac80211/main.c --@@ -287,7 +287,7 @@ void ieee80211_restart_hw(struct ieee802 -+@@ -285,7 +285,7 @@ void ieee80211_restart_hw(struct ieee802 - } - EXPORT_SYMBOL(ieee80211_restart_hw); - -@@ -9,7 +9,7 @@ - static int ieee80211_ifa_changed(struct notifier_block *nb, - unsigned long data, void *arg) - { --@@ -346,7 +346,7 @@ static int ieee80211_ifa_changed(struct -+@@ -344,7 +344,7 @@ static int ieee80211_ifa_changed(struct - } - #endif - -@@ -18,7 +18,7 @@ - static int ieee80211_ifa6_changed(struct notifier_block *nb, - unsigned long data, void *arg) - { --@@ -1031,14 +1031,14 @@ int ieee80211_register_hw(struct ieee802 -+@@ -1036,14 +1036,14 @@ int ieee80211_register_hw(struct ieee802 - goto fail_pm_qos; - } - -@@ -35,7 +35,7 @@ - local->ifa6_notifier.notifier_call = ieee80211_ifa6_changed; - result = register_inet6addr_notifier(&local->ifa6_notifier); - if (result) --@@ -1047,13 +1047,13 @@ int ieee80211_register_hw(struct ieee802 -+@@ -1052,13 +1052,13 @@ int ieee80211_register_hw(struct ieee802 - - return 0; - -@@ -52,7 +52,7 @@ - fail_ifa: - pm_qos_remove_notifier(PM_QOS_NETWORK_LATENCY, - &local->network_latency_notifier); --@@ -1086,10 +1086,10 @@ void ieee80211_unregister_hw(struct ieee -+@@ -1103,10 +1103,10 @@ void ieee80211_unregister_hw(struct ieee - - pm_qos_remove_notifier(PM_QOS_NETWORK_LATENCY, - &local->network_latency_notifier); -diff --git a/package/mac80211/patches/300-pending_work.patch b/package/mac80211/patches/300-pending_work.patch -index a1af6c2..3305388 100644 ---- a/package/mac80211/patches/300-pending_work.patch -+++ b/package/mac80211/patches/300-pending_work.patch -@@ -1,4153 +1,2752 @@ --commit 93f310a38a1d81a4bc8fcd9bf29628bd721cf2ef --Author: Felix Fietkau --Date: Sun Apr 6 23:35:28 2014 +0200 -- -- ath9k_hw: reduce ANI firstep range for older chips -- -- Use 0-8 instead of 0-16, which is closer to the old implementation. -- Also drop the overwrite of the firstep_low parameter to improve -- stability. -- -- Signed-off-by: Felix Fietkau -- --commit 584d297fd29fb39c76af25ae74ff9d5fe74c8a14 --Author: Helmut Schaa --Date: Wed Mar 12 10:37:55 2014 +0100 -- -- ath9k: Fix sequence number assignment for non-data frames -- -- Since commit 558ff225de80ac95b132d3a115ddadcd64498b4f (ath9k: fix -- ps-poll responses under a-mpdu sessions) non-data frames would have -- gotten a sequence number from a TIDs sequence counter instead of -- using the global sequence counter. -- -- This can lead to instable connections. -- -- To fix this only select the correct TID if we are processing a -- data frame. Furthermore, prevent non-data frames to get a sequence -- number from a TID sequence counter by adding a check to -- ath_tx_setup_buffer. -- -- Cc: Felix Fietkau -- Signed-off-by: Helmut Schaa -- --commit 3a0f984b1cdcd6a9f8c441635ef3b05d58547f4e --Author: Felix Fietkau --Date: Tue Mar 11 14:03:32 2014 +0100 -- -- ath9k_hw: set ANI firstep as absolute values instead of relative -- -- On older chips, the INI value differ in similar ways as cycpwr_thr1, so -- convert it to absolute values as well. -- -- Since the ANI algorithm is different here compared to the old -- implementation (fewer steps, controlled at a different point in time), -- it makes sense to use values similar to what would be applied for newer -- chips, just without relying on INI defaults. -- -- Signed-off-by: Felix Fietkau -- --commit 91d70d40400c569b49605b78fd7c43e9405694f4 --Author: Felix Fietkau --Date: Tue Mar 11 14:00:37 2014 +0100 -+commit d3a58df87a2e4c2301ac843604202d290a48440b -+Author: Avraham Stern -+Date: Thu May 22 12:17:47 2014 +0300 - -- ath9k_hw: set ANI cycpwr_thr1 as absolute values instead of relative -- -- The table was copied from the ANI implementation of AR9300. It assumes -- that the INI values contain a baseline value that is usable as reference -- from which to increase/decrease based on the noise immunity value. -+ mac80211: set new interfaces as idle upon init - -- On older chips, the differences are bigger and especially AR5008/AR9001 -- are configured to much more sensitive values than what is useful. -+ Mark new interfaces as idle to allow operations that require that -+ interfaces are idle to take place. Interface types that are always -+ not idle (like AP interfaces) will be set as not idle when they are -+ assigned a channel context. - -- Improve ANI behavior by reverting to the absolute values used in the -- previous implementation (expressed as a simple formula instead of the -- old table). -- -- Signed-off-by: Felix Fietkau -+ Signed-off-by: Avraham Stern -+ Signed-off-by: Emmanuel Grumbach -+ Signed-off-by: Johannes Berg - --commit c977493766310a825f406836636ffd66e1447783 --Author: Felix Fietkau --Date: Mon Mar 10 19:52:56 2014 +0100 -+commit 923eaf367206e01f22c97aee22300e332d071916 -+Author: Arik Nemtsov -+Date: Mon May 26 14:40:51 2014 +0300 - -- ath9k_hw: remove ANI function restrictions for AP mode -+ mac80211: don't check netdev state for debugfs read/write - -- The primary purpose of this piece of code was to selectively disable -- OFDM weak signal detection. The checks for this are elsewhere, and an -- earlier commit relaxed the restrictions for older chips, which are more -- sensitive to interference. -+ Doing so will lead to an oops for a p2p-dev interface, since it has -+ no netdev. - -- Signed-off-by: Felix Fietkau -- --commit 8d804f1af11e4e058b1e8453327777d73a585cb8 --Author: Felix Fietkau --Date: Sun Mar 9 11:25:43 2014 +0100 -+ Cc: stable@vger.kernel.org -+ Signed-off-by: Arik Nemtsov -+ Signed-off-by: Emmanuel Grumbach -+ Signed-off-by: Johannes Berg - -- ath9k: clean up and enhance ANI debugfs file -- -- Unify scnprintf calls and include the current OFDM/CCK immunity level. -- -- Signed-off-by: Felix Fietkau -+commit a9fb54169b197f31aff24c8d6270dd1e56cde395 -+Author: chaitanya.mgit@gmail.com -+Date: Mon May 26 18:01:44 2014 +0530 -+ -+ regdb: Generalize the mW to dBm power conversion -+ -+ Generalize the power conversion from mW to dBm -+ using log. This should fix the below compilation -+ error for country NO which adds a new power value -+ 2000mW which is not handled earlier. -+ -+ CC [M] net/wireless/wext-sme.o -+ CC [M] net/wireless/regdb.o -+ net/wireless/regdb.c:1130:1: error: Unknown undeclared here (not in -+ a function) -+ net/wireless/regdb.c:1130:9: error: expected } before power -+ make[2]: *** [net/wireless/regdb.o] Error 1 -+ make[1]: *** [net/wireless] Error 2 -+ make: *** [net] Error 2 -+ -+ Reported-By: John Walker -+ Signed-off-by: Chaitanya T K -+ Acked-by: John W. Linville -+ [remove unneeded parentheses, fix rounding by using %.0f] -+ Signed-off-by: Johannes Berg - --commit 22e298b5a3a8a49e33805d4e351965123dede35b --Author: Felix Fietkau --Date: Sun Mar 9 10:58:47 2014 +0100 -+commit c7d37a66e345df2fdf1aa7b2c9a6d3d53846ca5b -+Author: Krzysztof HaÅ‚asa -+Date: Mon May 26 14:14:46 2014 +0200 - -- ath9k: fix ready time of the multicast buffer queue -- -- qi->tqi_readyTime is written directly to registers that expect -- microseconds as unit instead of TU. -- When setting the CABQ ready time, cur_conf->beacon_interval is in TU, so -- convert it to microseconds before passing it to ath9k_hw. -+ mac80211: fix IBSS join by initializing last_scan_completed - -- This should hopefully fix some Tx DMA issues with buffered multicast -- frames in AP mode. -+ Without this fix, freshly rebooted Linux creates a new IBSS -+ instead of joining an existing one. Only when jiffies counter -+ overflows after 5 minutes the IBSS can be successfully joined. - -+ Signed-off-by: Krzysztof HaÅ‚asa -+ [edit commit message slightly] - Cc: stable@vger.kernel.org -- Signed-off-by: Felix Fietkau -- --commit fcb064fdd5a27bec8d24099bc0172468f34c97cb --Author: Felix Fietkau --Date: Sun Mar 9 09:43:09 2014 +0100 -+ Signed-off-by: Johannes Berg - -- ath9k_hw: fix unreachable code in baseband hang detection code -- -- The commit "ath9k: reduce baseband hang detection false positive rate" -- added a delay in the loop checking the baseband state, however it was -- unreachable due to previous 'continue' statements. -- -- Reported-by: Dan Carpenter -- Signed-off-by: Felix Fietkau -+commit 34171dc0d623be2c1032416bf7d3819f388ed70d -+Author: Emmanuel Grumbach -+Date: Sun May 25 15:35:41 2014 +0300 -+ -+ mac80211: fix virtual monitor interface addition -+ -+ Since the commit below, cfg80211_chandef_dfs_required() -+ will warn if it gets a an NL80211_IFTYPE_UNSPECIFIED iftype -+ as explicitely written in the commit log. -+ When an virtual monitor interface is added, its type is set -+ in ieee80211_sub_if_data.vif.type, but not in -+ ieee80211_sub_if_data.wdev.iftype which is passed to -+ cfg80211_chandef_dfs_required() hence resulting in the -+ following warning: -+ -+ WARNING: CPU: 1 PID: 21265 at net/wireless/chan.c:376 cfg80211_chandef_dfs_required+0xbc/0x130 [cfg80211]() -+ Modules linked in: [...] -+ CPU: 1 PID: 21265 Comm: ifconfig Tainted: G W O 3.13.11+ #12 -+ Hardware name: Dell Inc. Latitude E6410/0667CC, BIOS A01 03/05/2010 -+ 0000000000000009 ffff88008f5fdb08 ffffffff817d4219 ffff88008f5fdb50 -+ ffff88008f5fdb40 ffffffff8106f57d 0000000000000000 0000000000000000 -+ ffff880081062fb8 ffff8800810604e0 0000000000000001 ffff88008f5fdba0 -+ Call Trace: -+ [] dump_stack+0x4d/0x66 -+ [] warn_slowpath_common+0x7d/0xa0 -+ [] warn_slowpath_fmt+0x4c/0x50 -+ [] cfg80211_chandef_dfs_required+0xbc/0x130 [cfg80211] -+ [] ieee80211_vif_use_channel+0x94/0x500 [mac80211] -+ [] ieee80211_add_virtual_monitor+0x1ab/0x5c0 [mac80211] -+ [] ieee80211_do_open+0xe75/0x1580 [mac80211] -+ [] ieee80211_open+0x69/0x70 [mac80211] -+ [snip] -+ -+ Fixes: 00ec75fc5a64 ("cfg80211: pass the actual iftype when calling cfg80211_chandef_dfs_required()") -+ Signed-off-by: Emmanuel Grumbach -+ Acked-by: Luciano Coelho -+ Signed-off-by: Johannes Berg - --commit 31959d8df39319e32c6d5ba9c135727be90cfad7 -+commit d93cc72b37b4e2c314e1c499e80e8801907c2fea - Author: Michal Kazior --Date: Fri Mar 7 08:09:38 2014 +0100 -+Date: Thu Jun 5 14:21:37 2014 +0200 - -- mac80211: fix possible NULL dereference -- -- If chanctx is missing on a given vif then the band -- is assumed to be 2GHz. However if hw doesn't -- support 2GHz band then mac80211 ended up with a -- NULL dereference. -- -- This fixes a splat: -+ mac80211: use csa counter offsets instead of csa_active - -- [ 4605.207223] BUG: unable to handle kernel NULL pointer dereference at 0000000000000018 -- [ 4605.210789] IP: [] ieee80211_parse_bitrates+0x65/0x110 [mac80211] -+ vif->csa_active is protected by mutexes only. This -+ means it is unreliable to depend on it on codeflow -+ in non-sleepable beacon and CSA code. There was no -+ guarantee to have vif->csa_active update be -+ visible before beacons are updated on SMP systems. - -- The splat was preceeded by WARN_ON(!chanctx_conf) -- in ieee80211_get_sdata_band(). -+ Using csa counter offsets which are embedded in -+ beacon struct (and thus are protected with single -+ RCU assignment) is much safer. - - Signed-off-by: Michal Kazior -- --commit 6c5a3ffa0a2d22c091a2717f427259bacf77ac5e --Author: Michael Braun --Date: Thu Mar 6 15:08:43 2014 +0100 -- -- mac80211: fix WPA with VLAN on AP side with ps-sta again -- -- commit de74a1d9032f4d37ea453ad2a647e1aff4cd2591 -- "mac80211: fix WPA with VLAN on AP side with ps-sta" -- fixed an issue where queued multicast packets would -- be sent out encrypted with the key of an other bss. -- -- commit "7cbf9d017dbb5e3276de7d527925d42d4c11e732" -- "mac80211: fix oops on mesh PS broadcast forwarding" -- essentially reverted it, because vif.type cannot be AP_VLAN -- due to the check to vif.type in ieee80211_get_buffered_bc before. -- -- As the later commit intended to fix the MESH case, fix it -- by checking for IFTYPE_AP instead of IFTYPE_AP_VLAN. -- -- Fixes: 7cbf9d017dbb -- Cc: # 3.10.x -- Cc: # 3.11.x -- Cc: # 3.12.x -- Cc: # 3.13.x -- Cc: -- Cc: -- Signed-off-by: Michael Braun -- --commit 9d6ab9bdb9b368a6cf9519f0f92509b5b2c297ec --Author: Johannes Berg --Date: Mon Mar 3 14:19:08 2014 +0100 -- -- cfg80211: remove racy beacon_interval assignment -- -- In case of AP mode, the beacon interval is already reset to -- zero inside cfg80211_stop_ap(), and in the other modes it -- isn't relevant. Remove the assignment to remove a potential -- race since the assignment isn't properly locked. -- -- Reported-by: Michal Kazior - Signed-off-by: Johannes Berg - --commit 1abdeca3c6fb9cf1f84f85e78ed8d1c33bd69db0 --Author: Felix Fietkau --Date: Fri Feb 28 18:52:56 2014 +0100 -- -- ath9k_hw: tweak noise immunity thresholds for older chipsets -- -- Older chipsets are more sensitive to high PHY error counts, and the -- current noise immunity thresholds were based on tests run at QCA with -- newer chipsets. -- -- This patch brings back the values from the old ANI implementation for -- old chipsets, and it also disables weak signal detection on an earlier -- noise immunity level, to improve overall radio stability on affected -- devices. -- -- Signed-off-by: Felix Fietkau -- --commit 431e506da5953adc3b65af25f4b90873d528c115 --Author: Felix Fietkau --Date: Fri Feb 28 18:44:13 2014 +0100 -- -- ath9k_hw: toggle weak signal detection in AP mode on older chipsets -- -- The commit 80b4205b "ath9k: Fix OFDM weak signal detection for AP mode" -- prevented weak signal detection changes from taking effect in AP mode on -- all chipsets, claiming it is "not allowed". -- -- The main reason for not disabling weak signal detection in AP mode is -- that typically beacon RSSI is used to track whether it is needed to -- boost range, and this is unavailable in AP mode for obvious reasons. -- -- The problem with not disabling weak signal detection is that older -- chipsets are very sensitive to high PHY error counts. When faced with -- heavy noise, this can lead to an excessive amount of "Failed to stop -- TX DMA" errors in the field. -- -- Signed-off-by: Felix Fietkau -- --commit 98d1a6c5b14688ed030e81b889f607be308e0df9 --Author: Felix Fietkau --Date: Mon Feb 24 22:20:32 2014 +0100 -- -- ath9k: fix invalid descriptor discarding -- -- Only set sc->rx.discard_next to rx_stats->rs_more when actually -- discarding the current descriptor. -- -- Also, fix a detection of broken descriptors: -- First the code checks if the current descriptor is not done. -- Then it checks if the next descriptor is done. -- Add a check that afterwards checks the first descriptor again, because -- it might have been completed in the mean time. -- -- This fixes a regression introduced in -- commit 723e711356b5a8a95728a890e254e8b0d47b55cf -- "ath9k: fix handling of broken descriptors" -- -- Cc: stable@vger.kernel.org -- Reported-by: Marco André Dinis -- Signed-off-by: Felix Fietkau -- --commit 52a46300e782fe6994466523eb2b0b59091ea59f --Author: Felix Fietkau --Date: Mon Feb 24 11:43:50 2014 +0100 -- -- ath9k: reduce baseband hang detection false positive rate -- -- Check if the baseband state remains stable, and add a small delay -- between register reads. -- -- Signed-off-by: Felix Fietkau -- --commit 118945bb12082e9d4edddc868d88143164e0f440 --Author: Felix Fietkau --Date: Sat Feb 22 14:55:23 2014 +0100 -- -- ath5k: set SURVEY_INFO_IN_USE on get_survey -- -- Only one channel is returned - the one currently being used. -- -- Signed-off-by: Felix Fietkau -- --commit ee41f72476e1ea44283dfe1cbf75b9543a1e15c8 --Author: Felix Fietkau --Date: Sat Feb 22 14:44:52 2014 +0100 -- -- ath9k: make some hardware reset log messages debug-only -- -- On some chips, baseband watchdog hangs are more common than others, and -- the driver has support for handling them. -- Interrupts even after a watchdog hang are also quite common, so there's -- not much point in spamming the user's logfiles. -- -- Signed-off-by: Felix Fietkau -- --commit b14fbb554fc65a2e0b5c41a319269b0350f187e7 --Author: Felix Fietkau --Date: Sat Feb 22 14:35:25 2014 +0100 -- -- ath9k: do not set half/quarter channel flags in AR_PHY_MODE -- -- 5/10 MHz channel bandwidth is configured via the PLL clock, instead of -- the AR_PHY_MODE register. Using that register is AR93xx specific, and -- makes the mode incompatible with earlier chipsets. -- -- In some early versions, these flags were apparently applied at the wrong -- point in time and thus did not cause connectivity issues, however now -- they are causing problems, as pointed out in this OpenWrt ticket: -- -- https://dev.openwrt.org/ticket/14916 -- -- Signed-off-by: Felix Fietkau -- --commit 0f1cb7be2551b30b02cd54c897e0e29e483cfda5 --Author: Felix Fietkau --Date: Sat Feb 22 13:43:29 2014 +0100 -+commit d2746694fcdef24e0a7a1947d8c70082cde81a26 -+Author: Michal Kazior -+Date: Thu Jun 5 14:21:36 2014 +0200 - -- ath9k: fix ps-poll responses under a-mpdu sessions -- -- When passing tx frames to the U-APSD queue for powersave poll responses, -- the ath_atx_tid pointer needs to be passed to ath_tx_setup_buffer for -- proper sequence number accounting. -+ mac80211: move csa counters from sdata to beacon/presp - -- This fixes high latency and connection stability issues with ath9k -- running as AP and a few kinds of mobile phones as client, when PS-Poll -- is heavily used -- -- Cc: stable@vger.kernel.org -- Signed-off-by: Felix Fietkau -- --commit d5d87a37bbd6066b2c3c5d0bd0fe2a6e2ea45cc5 --Author: Felix Fietkau --Date: Fri Feb 21 11:39:59 2014 +0100 -- -- ath9k: list more reset causes in debugfs -+ Having csa counters part of beacon and probe_resp -+ structures makes it easier to get rid of possible -+ races between setting a beacon and updating -+ counters on SMP systems by guaranteeing counters -+ are always consistent against given beacon struct. - -- Number of MAC hangs and stuck beacons were missing -+ While at it relax WARN_ON into WARN_ON_ONCE to -+ prevent spamming logs and racing. - -- Signed-off-by: Felix Fietkau -+ Signed-off-by: Michal Kazior -+ Signed-off-by: Johannes Berg - --commit d84856012e0f10fe598a5ad3b7b869397a089e07 --Author: Johannes Berg --Date: Thu Feb 20 11:19:58 2014 +0100 -+commit 5dcb54f3a1a8cd7e0331e773487574f9743615db -+Author: Janusz Dziedzic -+Date: Thu Jun 5 08:12:57 2014 +0200 - -- mac80211: fix station wakeup powersave race -- -- Consider the following (relatively unlikely) scenario: -- 1) station goes to sleep while frames are buffered in driver -- 2) driver blocks wakeup (until no more frames are buffered) -- 3) station wakes up again -- 4) driver unblocks wakeup -+ mac80211: allow tx via monitor iface when DFS - -- In this case, the current mac80211 code will do the following: -- 1) WLAN_STA_PS_STA set -- 2) WLAN_STA_PS_DRIVER set -- 3) - nothing - -- 4) WLAN_STA_PS_DRIVER cleared -+ Allow send frames using monitor interface -+ when DFS chandef and we pass CAC (beaconing -+ allowed). - -- As a result, no frames will be delivered to the client, even -- though it is awake, until it sends another frame to us that -- triggers ieee80211_sta_ps_deliver_wakeup() in sta_ps_end(). -- -- Since we now take the PS spinlock, we can fix this while at -- the same time removing the complexity with the pending skb -- queue function. This was broken since my commit 50a9432daeec -- ("mac80211: fix powersaving clients races") due to removing -- the clearing of WLAN_STA_PS_STA in the RX path. -- -- While at it, fix a cleanup path issue when a station is -- removed while the driver is still blocking its wakeup. -+ This fix problem when old kernel and new backports used, -+ in such case hostapd create/use also monitor interface. -+ Before this patch all frames hostapd send using monitor -+ iface were dropped when AP was configured on DFS channel. - -+ Signed-off-by: Janusz Dziedzic - Signed-off-by: Johannes Berg - --commit 798f2786602cbe93e6b928299614aa36ebf50692 -+commit 6f09a1beb0d2007572248c986780562219bd206f - Author: Johannes Berg --Date: Mon Feb 17 20:49:03 2014 +0100 -+Date: Wed Jun 4 17:31:56 2014 +0200 - -- mac80211: insert stations before adding to driver -- -- There's a race condition in mac80211 because we add stations -- to the internal lists after adding them to the driver, which -- means that (for example) the following can happen: -- 1. a station connects and is added -- 2. first, it is added to the driver -- 3. then, it is added to the mac80211 lists -+ cfg80211: make ethtool the driver's responsibility - -- If the station goes to sleep between steps 2 and 3, and the -- firmware/hardware records it as being asleep, mac80211 will -- never instruct the driver to wake it up again as it never -- realized it went to sleep since the RX path discarded the -- frame as a "spurious class 3 frame", no station entry was -- present yet. -+ Currently, cfg80211 tries to implement ethtool, but that doesn't -+ really scale well, with all the different operations. Make the -+ lower-level driver responsible for it, which currently only has -+ an effect on mac80211. It will similarly not scale well at that -+ level though, since mac80211 also has many drivers. - -- Fix this by adding the station in software first, and only -- then adding it to the driver. That way, any state that the -- driver changes will be reflected properly in mac80211's -- station state. The problematic part is the roll-back if the -- driver fails to add the station, in that case a bit more is -- needed. To not make that overly complex prevent starting BA -- sessions in the meantime. -+ To cleanly implement this in mac80211, introduce a new file and -+ move some code to appropriate places. - - Signed-off-by: Johannes Berg - --commit b9ba6a520cb07ab3aa7aaaf9ce4a0bc7a6bc06fe --Author: Emmanuel Grumbach --Date: Thu Feb 20 09:22:11 2014 +0200 -+commit 6b0c6f133de8f90caeb1c4a902e6140567c5bf96 -+Author: Johannes Berg -+Date: Wed Jun 4 17:06:23 2014 +0200 - -- mac80211: fix AP powersave TX vs. wakeup race -- -- There is a race between the TX path and the STA wakeup: while -- a station is sleeping, mac80211 buffers frames until it wakes -- up, then the frames are transmitted. However, the RX and TX -- path are concurrent, so the packet indicating wakeup can be -- processed while a packet is being transmitted. -- -- This can lead to a situation where the buffered frames list -- is emptied on the one side, while a frame is being added on -- the other side, as the station is still seen as sleeping in -- the TX path. -+ mac80211: remove weak WEP IV accounting - -- As a result, the newly added frame will not be send anytime -- soon. It might be sent much later (and out of order) when the -- station goes to sleep and wakes up the next time. -+ Since WEP is practically dead, there seems very little -+ point in keeping WEP weak IV accounting. - -- Additionally, it can lead to the crash below. -- -- Fix all this by synchronising both paths with a new lock. -- Both path are not fastpath since they handle PS situations. -- -- In a later patch we'll remove the extra skb queue locks to -- reduce locking overhead. -- -- BUG: unable to handle kernel -- NULL pointer dereference at 000000b0 -- IP: [] ieee80211_report_used_skb+0x11/0x3e0 [mac80211] -- *pde = 00000000 -- Oops: 0000 [#1] SMP DEBUG_PAGEALLOC -- EIP: 0060:[] EFLAGS: 00210282 CPU: 1 -- EIP is at ieee80211_report_used_skb+0x11/0x3e0 [mac80211] -- EAX: e5900da0 EBX: 00000000 ECX: 00000001 EDX: 00000000 -- ESI: e41d00c0 EDI: e5900da0 EBP: ebe458e4 ESP: ebe458b0 -- DS: 007b ES: 007b FS: 00d8 GS: 00e0 SS: 0068 -- CR0: 8005003b CR2: 000000b0 CR3: 25a78000 CR4: 000407d0 -- DR0: 00000000 DR1: 00000000 DR2: 00000000 DR3: 00000000 -- DR6: ffff0ff0 DR7: 00000400 -- Process iperf (pid: 3934, ti=ebe44000 task=e757c0b0 task.ti=ebe44000) -- iwlwifi 0000:02:00.0: I iwl_pcie_enqueue_hcmd Sending command LQ_CMD (#4e), seq: 0x0903, 92 bytes at 3[3]:9 -- Stack: -- e403b32c ebe458c4 00200002 00200286 e403b338 ebe458cc c10960bb e5900da0 -- ff76a6ec ebe458d8 00000000 e41d00c0 e5900da0 ebe458f0 ff6f1b75 e403b210 -- ebe4598c ff723dc1 00000000 ff76a6ec e597c978 e403b758 00000002 00000002 -- Call Trace: -- [] ieee80211_free_txskb+0x15/0x20 [mac80211] -- [] invoke_tx_handlers+0x1661/0x1780 [mac80211] -- [] ieee80211_tx+0x75/0x100 [mac80211] -- [] ieee80211_xmit+0x8f/0xc0 [mac80211] -- [] ieee80211_subif_start_xmit+0x4fe/0xe20 [mac80211] -- [] dev_hard_start_xmit+0x450/0x950 -- [] sch_direct_xmit+0xa9/0x250 -- [] __qdisc_run+0x4b/0x150 -- [] dev_queue_xmit+0x2c2/0xca0 -- -- Cc: stable@vger.kernel.org -- Reported-by: Yaara Rozenblum -- Signed-off-by: Emmanuel Grumbach -- Reviewed-by: Stanislaw Gruszka -- [reword commit log, use a separate lock] - Signed-off-by: Johannes Berg - --commit 80e419de0dff38436b30d363311c625766193f86 --Author: Inbal Hacohen --Date: Wed Feb 12 09:32:27 2014 +0200 -+commit aecdc89fb4664c76baa4bbd46008f220532309ff -+Author: Luciano Coelho -+Date: Fri May 23 11:04:50 2014 +0300 - -- cfg80211: bugfix in regulatory user hint process -+ ath9k/ath10k: remove unnecessary channel_switch_beacon callbacks - -- After processing hint_user, we would want to schedule the -- timeout work only if we are actually waiting to CRDA. This happens -- when the status is not "IGNORE" nor "ALREADY_SET". -+ The channel_switch_beacon callback is optional, so it doesn't have to -+ be defined if it's not going to do anything useful with it. Both -+ ath9k and ath10k define the callback and just returns. This commit -+ removes them. - -- Signed-off-by: Inbal Hacohen -- Signed-off-by: Johannes Berg -+ Cc: Michal Kazior -+ Signed-off-by: Luciano Coelho -+ Signed-off-by: Kalle Valo - --commit 6514c93afede55284e2cb63359aadedb85884c80 --Author: Jouni Malinen --Date: Tue Feb 18 20:41:08 2014 +0200 -+commit 60ccc107c9b9fb732fdee1f76bb2dad44f0e1798 -+Author: Rajkumar Manoharan -+Date: Tue May 27 16:58:02 2014 +0530 - -- ath9k: Enable U-APSD AP mode support -+ ath9k: Fix deadlock while updating p2p beacon timer - -- mac80211 handles the actual operations, so ath9k can just indicate -- support for this. Based on initial tests, this combination seems to -- work fine. -+ pm_lock is taken twice while syncing HW TSF of p2p vif. -+ Fix this by taking the lock at caller side. - -- Signed-off-by: Jouni Malinen -+ Cc: Felix Fietkau -+ Signed-off-by: Rajkumar Manoharan -+ Signed-off-by: John W. Linville - --commit a63caf0a357ad5c1f08d6b7827dc76c451445017 -+commit f3831a4e3903dbc1a57d5df56deb6a143fd001bc - Author: Stanislaw Gruszka --Date: Wed Feb 19 13:15:17 2014 +0100 -+Date: Thu Jun 5 13:52:27 2014 +0200 - -- ath9k: protect tid->sched check -- -- We check tid->sched without a lock taken on ath_tx_aggr_sleep(). That -- is race condition which can result of doing list_del(&tid->list) twice -- (second time with poisoned list node) and cause crash like shown below: -+ rt2x00: do not initialize BCN_OFFSET registers - -- [424271.637220] BUG: unable to handle kernel paging request at 00100104 -- [424271.637328] IP: [] ath_tx_aggr_sleep+0x62/0xe0 [ath9k] -- ... -- [424271.639953] Call Trace: -- [424271.639998] [] ? ath9k_get_survey+0x110/0x110 [ath9k] -- [424271.640083] [] ath9k_sta_notify+0x42/0x50 [ath9k] -- [424271.640177] [] sta_ps_start+0x8f/0x1c0 [mac80211] -- [424271.640258] [] ? free_compound_page+0x2e/0x40 -- [424271.640346] [] ieee80211_rx_handlers+0x9d5/0x2340 [mac80211] -- [424271.640437] [] ? kmem_cache_free+0x1d8/0x1f0 -- [424271.640510] [] ? kfree_skbmem+0x34/0x90 -- [424271.640578] [] ? put_page+0x2c/0x40 -- [424271.640640] [] ? kfree_skbmem+0x34/0x90 -- [424271.640706] [] ? kfree_skbmem+0x34/0x90 -- [424271.640787] [] ? ieee80211_rx_handlers_result+0x73/0x1d0 [mac80211] -- [424271.640897] [] ieee80211_prepare_and_rx_handle+0x520/0xad0 [mac80211] -- [424271.641009] [] ? ieee80211_rx_handlers+0x2ed/0x2340 [mac80211] -- [424271.641104] [] ? ip_output+0x7e/0xd0 -- [424271.641182] [] ieee80211_rx+0x307/0x7c0 [mac80211] -- [424271.641266] [] ath_rx_tasklet+0x88e/0xf70 [ath9k] -- [424271.641358] [] ? ieee80211_rx+0x1dc/0x7c0 [mac80211] -- [424271.641445] [] ath9k_tasklet+0xcb/0x130 [ath9k] -+ We setup BCN_OFFSET{0,1} registers dynamically, don't have to -+ initialize them. - -- Bug report: -- https://bugzilla.kernel.org/show_bug.cgi?id=70551 -- -- Reported-and-tested-by: Max Sydorenko -- Cc: stable@vger.kernel.org - Signed-off-by: Stanislaw Gruszka - --commit 82ed9e3ccc02797df2ffe4b78127c4cd5f799a41 --Author: Felix Fietkau --Date: Tue Feb 11 15:54:13 2014 +0100 -- -- mac80211: send control port protocol frames to the VO queue -- -- Improves reliability of wifi connections with WPA, since authentication -- frames are prioritized over normal traffic and also typically exempt -- from aggregation. -- -- Cc: stable@vger.kernel.org -- Signed-off-by: Felix Fietkau -- --commit d4426800f71e972feaa33e04c5801fc730627bdd --Author: Stanislaw Gruszka --Date: Mon Feb 10 22:38:28 2014 +0100 -- -- rtl8187: fix regression on MIPS without coherent DMA -- -- This patch fixes regression caused by commit a16dad77634 "MIPS: Fix -- potencial corruption". That commit fixes one corruption scenario in -- cost of adding another one, which actually start to cause crashes -- on Yeeloong laptop when rtl8187 driver is used. -- -- For correct DMA read operation on machines without DMA coherence, kernel -- have to invalidate cache, such it will refill later with new data that -- device wrote to memory, when that data is needed to process. We can only -- invalidate full cache line. Hence when cache line includes both dma -- buffer and some other data (written in cache, but not yet in main -- memory), the other data can not hit memory due to invalidation. That -- happen on rtl8187 where struct rtl8187_priv fields are located just -- before and after small buffers that are passed to USB layer and DMA -- is performed on them. -- -- To fix the problem we align buffers and reserve space after them to make -- them match cache line. -- -- This patch does not resolve all possible MIPS problems entirely, for -- that we have to assure that we always map cache aligned buffers for DMA, -- what can be complex or even not possible. But patch fixes visible and -- reproducible regression and seems other possible corruptions do not -- happen in practice, since Yeeloong laptop works stable without rtl8187 -- driver. -- -- Bug report: -- https://bugzilla.kernel.org/show_bug.cgi?id=54391 -- -- Reported-by: Petr Pisar -- Bisected-by: Tom Li -- Reported-and-tested-by: Tom Li -- Cc: stable@vger.kernel.org -- Signed-off-by: Stanislaw Gruszka -- --commit e2f141d67ad1e7fe10aaab61811e8a409dfb2442 --Author: Sujith Manoharan --Date: Fri Feb 7 10:29:55 2014 +0530 -- -- ath9k: Calculate IQ-CAL median -- -- This patch adds a routine to calculate the median IQ correction -- values for AR955x, which is used for outlier detection. -- The normal method which is used for all other chips is -- bypassed for AR955x. -- -- Signed-off-by: Sujith Manoharan -- --commit c52a6fce0820c8d0687443ab86058ae03b478c8f --Author: Sujith Manoharan --Date: Fri Feb 7 10:29:54 2014 +0530 -- -- ath9k: Expand the IQ coefficient array -- -- This will be used for storing data for mutiple -- IQ calibration runs, for AR955x. -- -- Signed-off-by: Sujith Manoharan -- --commit 034969ff5c2b6431d10e07c1938f0b916da85cc3 --Author: Sujith Manoharan --Date: Fri Feb 7 10:29:53 2014 +0530 -- -- ath9k: Modify IQ calibration for AR955x -- -- IQ calibration post-processing for AR955x is different -- from other chips - instead of just doing it as part -- of AGC calibration once, it is triggered 3 times and -- a median is determined. This patch adds initial support -- for changing the calibration behavior for AR955x. -- -- Also, to simplify things, a helper routine to issue/poll -- AGC calibration is used. -- -- For non-AR955x chips, the iqcal_idx (which will be used -- in subsequent patches) is set to zero. -- -- Signed-off-by: Sujith Manoharan -- --commit 9b1ed6454e6f3511f24266be99b4e403f243f6a8 --Author: Sujith Manoharan --Date: Fri Feb 7 10:29:52 2014 +0530 -- -- ath9k: Fix magnitude/phase calculation -- -- Incorrect values are programmed in the registers -- containing the IQ correction coefficients by the IQ-CAL -- post-processing code. Fix this. -- -- Signed-off-by: Sujith Manoharan -- --commit 36f93484f96f79171dcecb67c5ef0c3de22531a6 --Author: Sujith Manoharan --Date: Fri Feb 7 10:29:51 2014 +0530 -- -- ath9k: Rename ar9003_hw_tx_iqcal_load_avg_2_passes -- -- Use ar9003_hw_tx_iq_cal_outlier_detection instead. -- -- Signed-off-by: Sujith Manoharan -- --commit 3af09a7f5d21dd5fd15b973ce6a91a575da30417 --Author: Sujith Manoharan --Date: Fri Feb 7 10:29:50 2014 +0530 -- -- ath9k: Check explicitly for IQ calibration -- -- In chips like AR955x, the initvals contain the information -- whether IQ calibration is to be done in the HW when an -- AGC calibration is triggered. Check if IQ-CAL is enabled -- in the initvals before flagging 'txiqcal_done' as true. -- -- Signed-off-by: Sujith Manoharan -- --commit cb4969634b93c4643a32cc3fbd27d2b288b25771 --Author: Sujith Manoharan --Date: Fri Feb 7 10:29:49 2014 +0530 -+commit e5c58ca7a48d4c82f282749a978052c47fd95998 -+Author: Stanislaw Gruszka -+Date: Thu Jun 5 13:52:26 2014 +0200 - -- ath9k: Fix IQ cal post processing for SoC -+ rt2x00: change order when stop beaconing - -- Calibration data is not reused for SoC chips, so -- call ar9003_hw_tx_iq_cal_post_proc() with the correct -- argument. The 'is_reusable' flag is currently used -- only for PC-OEM chips, but it makes things clearer to -- specify it explicity. -+ When no beaconing is needed, first stop beacon queue (disable beaconing -+ globally) to avoid possible sending of not prepared beacon on short -+ period after clearing beacon and before stop of BCN queue. - -- Signed-off-by: Sujith Manoharan -+ Signed-off-by: Stanislaw Gruszka - --commit e138e0ef9560c46ce93dbb22a728a57888e94d1c --Author: Sujith Manoharan --Date: Mon Feb 3 13:31:37 2014 +0530 -+commit 382c1b9e03f52d0cd741ef1d942cad0f649f0744 -+Author: Stanislaw Gruszka -+Date: Thu Jun 5 13:52:25 2014 +0200 - -- ath9k: Fix TX power calculation -+ rt2x00: change default MAC_BSSID_DW1_BSS_BCN_NUM - -- The commit, "ath9k_hw: Fix incorrect Tx control power in AR9003 template" -- fixed the incorrect values in the eeprom templates, but if -- boards have already been calibrated with incorrect values, -- they would still be using the wrong TX power. Fix this by assigning -- a default value in such cases. -+ We setup MAC_BSSID_DW1_BSS_BCN_NUM dynamically when numbers of active -+ beacons increase. Change default to 0 to tell hardware that we want to -+ send only one beacon as default. - -- Cc: Rajkumar Manoharan -- Signed-off-by: Sujith Manoharan -+ Signed-off-by: Stanislaw Gruszka - --commit b9f268b5b01331c3c82179abca551429450e9417 --Author: Michal Kazior --Date: Wed Jan 29 14:22:27 2014 +0100 -+commit 3b400571dd033e46fa7e76c5bb92a3ce8198afa9 -+Author: Stanislaw Gruszka -+Date: Thu Jun 5 13:52:24 2014 +0200 - -- cfg80211: consider existing DFS interfaces -- -- It was possible to break interface combinations in -- the following way: -- -- combo 1: iftype = AP, num_ifaces = 2, num_chans = 2, -- combo 2: iftype = AP, num_ifaces = 1, num_chans = 1, radar = HT20 -+ rt2x00: change beaconing setup on RT2800 - -- With the above interface combinations it was -- possible to: -+ As reported by Matthias, on 5572 chip, even if we clear up TXWI -+ of corresponding beacon, hardware still try to send it or do other -+ action that increase power consumption peak up to 1A. - -- step 1. start AP on DFS channel by matching combo 2 -- step 2. start AP on non-DFS channel by matching combo 1 -+ To avoid the issue, setup beaconing dynamically by configuring offsets -+ of currently active beacons and MAC_BSSID_DW1_BSS_BCN_NUM variable, -+ which limit number of beacons that hardware will try to send. - -- This was possible beacuse (step 2) did not consider -- if other interfaces require radar detection. -- -- The patch changes how cfg80211 tracks channels - -- instead of channel itself now a complete chandef -- is stored. -- -- Signed-off-by: Michal Kazior -- Signed-off-by: Johannes Berg -+ Reported-by: Matthias Fend -+ Signed-off-by: Stanislaw Gruszka - --commit bc9c62f5f511cc395c62dbf4cdd437f23db53b28 --Author: Antonio Quartulli --Date: Wed Jan 29 17:53:43 2014 +0100 -+commit 916e591b2cc41f7e572992175ca56d866d7bc958 -+Author: Stanislaw Gruszka -+Date: Thu Jun 5 13:52:23 2014 +0200 - -- cfg80211: fix channel configuration in IBSS join -- -- When receiving an IBSS_JOINED event select the BSS object -- based on the {bssid, channel} couple rather than the bssid -- only. -- With the current approach if another cell having the same -- BSSID (but using a different channel) exists then cfg80211 -- picks up the wrong BSS object. -- The result is a mismatching channel configuration between -- cfg80211 and the driver, that can lead to any sort of -- problem. -- -- The issue can be triggered by having an IBSS sitting on -- given channel and then asking the driver to create a new -- cell using the same BSSID but with a different frequency. -- By passing the channel to cfg80211_get_bss() we can solve -- this ambiguity and retrieve/create the correct BSS object. -- All the users of cfg80211_ibss_joined() have been changed -- accordingly. -+ rt2x00: change beaconing locking - -- Moreover WARN when cfg80211_ibss_joined() gets a NULL -- channel as argument and remove a bogus call of the same -- function in ath6kl (it does not make sense to call -- cfg80211_ibss_joined() with a zero BSSID on ibss-leave). -+ This patch is needed for further changes to keep global variables -+ consistent when changing beaconing on diffrent vif's. - -- Cc: Kalle Valo -- Cc: Arend van Spriel -- Cc: Bing Zhao -- Cc: Jussi Kivilinna -- Cc: libertas-dev@lists.infradead.org -- Acked-by: Kalle Valo -- Signed-off-by: Antonio Quartulli -- [minor code cleanup in ath6kl] -- Signed-off-by: Johannes Berg -+ Signed-off-by: Stanislaw Gruszka - --commit 7e0c41cb41f215aba2c39b1c237bb4d42ec49a85 -+commit 930b0dffd1731f3f418f9132faea720a23b7af61 - Author: Johannes Berg --Date: Fri Jan 24 14:41:44 2014 +0100 -- -- mac80211: fix bufferable MMPDU RX handling -- -- Action, disassoc and deauth frames are bufferable, and as such don't -- have the PM bit in the frame control field reserved which means we -- need to react to the bit when receiving in such a frame. -- -- Fix this by introducing a new helper ieee80211_is_bufferable_mmpdu() -- and using it for the RX path that currently ignores the PM bit in -- any non-data frames for doze->wake transitions, but listens to it in -- all frames for wake->doze transitions, both of which are wrong. -- -- Also use the new helper in the TX path to clean up the code. -- -- Signed-off-by: Johannes Berg -- --commit fc0df6d2343636e3f48a069330d5b972e3d8659d --Author: Janusz Dziedzic --Date: Fri Jan 24 14:29:21 2014 +0100 -- -- cfg80211: set preset_chandef after channel switch -- -- Set preset_chandef in channel switch notification. -- In other case we will have old preset_chandef. -- -- Signed-off-by: Janusz Dziedzic -- Signed-off-by: Johannes Berg -- --commit cdec895e2344987ff171cece96e25d7407a3ebf6 --Author: Simon Wunderlich --Date: Fri Jan 24 23:48:29 2014 +0100 -- -- mac80211: send ibss probe responses with noack flag -- -- Responding to probe requests for scanning clients will often create -- excessive retries, as it happens quite often that the scanning client -- already left the channel. Therefore do it like hostapd and send probe -- responses for wildcard SSID only once by using the noack flag. -+Date: Tue Jun 3 11:18:47 2014 +0200 -+ -+ mac80211: fix station/driver powersave race -+ -+ It is currently possible to have a race due to the station PS -+ unblock work like this: -+ * station goes to sleep with frames buffered in the driver -+ * driver blocks wakeup -+ * station wakes up again -+ * driver flushes/returns frames, and unblocks, which schedules -+ the unblock work -+ * unblock work starts to run, and checks that the station is -+ awake (i.e. that the WLAN_STA_PS_STA flag isn't set) -+ * we process a received frame with PM=1, setting the flag again -+ * ieee80211_sta_ps_deliver_wakeup() runs, delivering all frames -+ to the driver, and then clearing the WLAN_STA_PS_DRIVER and -+ WLAN_STA_PS_STA flags -+ -+ In this scenario, mac80211 will think that the station is awake, -+ while it really is asleep, and any TX'ed frames should be filtered -+ by the device (it will know that the station is sleeping) but then -+ passed to mac80211 again, which will not buffer it either as it -+ thinks the station is awake, and eventually the packets will be -+ dropped. -+ -+ Fix this by moving the clearing of the flags to exactly where we -+ learn about the situation. This creates a problem of reordering, -+ so introduce another flag indicating that delivery is being done, -+ this new flag also queues frames and is cleared only while the -+ spinlock is held (which the queuing code also holds) so that any -+ concurrent delivery/TX is handled correctly. - -- Signed-off-by: Simon Wunderlich -- [fix typo & 'wildcard SSID' in commit log] -+ Reported-by: Andrei Otcheretianski - Signed-off-by: Johannes Berg - --commit 0b865d1e6b9c05052adae9315df7cb195dc60c3b --Author: Luciano Coelho --Date: Tue Jan 28 17:09:08 2014 +0200 -+commit 6df35206bc6c1c6aad1d8077df5786b4a7f77873 -+Author: Felix Fietkau -+Date: Fri May 23 19:58:14 2014 +0200 - -- mac80211: ibss: remove unnecessary call to release channel -- -- The ieee80211_vif_use_channel() function calls -- ieee80211_vif_release_channel(), so there's no need to call it -- explicitly in __ieee80211_sta_join_ibss(). -+ mac80211: reduce packet loss notifications under load - -- Signed-off-by: Luciano Coelho -- Signed-off-by: Johannes Berg -- --commit e1b6c17e971f0a51ff86c2dac2584c63cd999cd7 --Author: Michal Kazior --Date: Wed Jan 29 07:56:21 2014 +0100 -- -- mac80211: add missing CSA locking -+ During strong signal fluctuations under high throughput, few consecutive -+ failed A-MPDU transmissions can easily trigger packet loss notification, -+ and thus (in AP mode) client disconnection. - -- The patch adds a missing sdata lock and adds a few -- lockdeps for easier maintenance. -+ Reduce the number of false positives by checking the A-MPDU status flag -+ and treating a failed A-MPDU as a single packet. - -- Signed-off-by: Michal Kazior -- Signed-off-by: Johannes Berg -+ Signed-off-by: Felix Fietkau - --commit ad17ba7d14d225b109b73c177cd446afb8050598 --Author: Michal Kazior --Date: Wed Jan 29 07:56:20 2014 +0100 -+commit 7b7843a36fbcc568834404c7430ff895d8502131 -+Author: Felix Fietkau -+Date: Fri May 23 19:26:32 2014 +0200 - -- mac80211: fix sdata->radar_required locking -+ mac80211: fix a memory leak on sta rate selection table - -- radar_required setting wasn't protected by -- local->mtx in some places. This should prevent -- from scanning/radar detection/roc colliding. -- -- Signed-off-by: Michal Kazior -- Signed-off-by: Johannes Berg -+ Cc: stable@vger.kernel.org -+ Reported-by: Christophe Prévotaux -+ Signed-off-by: Felix Fietkau - --commit 5fcd5f1808813a3d9e502fd756e01bee8a79c85d --Author: Michal Kazior --Date: Wed Jan 29 07:56:19 2014 +0100 -+commit 96892d6aa0a153423070addf3070bc79578b3897 -+Author: Felix Fietkau -+Date: Mon May 19 21:20:49 2014 +0200 - -- mac80211: move csa_active setting in STA CSA -+ ath9k: avoid passing buffers to the hardware during flush - -- The sdata->vif.csa_active could be left set after, -- e.g. channel context constraints check fail in STA -- mode leaving the interface in a strange state for -- a brief period of time until it is disconnected. -- This was harmless but ugly. -+ The commit "ath9k: fix possible hang on flush" changed the receive code -+ to always link rx descriptors of processed frames, even when flushing. -+ In some cases, this leads to flushed rx buffers being passed to the -+ hardware while rx is already stopped. - -- Signed-off-by: Michal Kazior -- Reviewed-by: Luciano Coelho -- Signed-off-by: Johannes Berg -- --commit e486da4b7eed71821c6b4c1bb9ac62ffd3ab13e9 --Author: Michal Kazior --Date: Wed Jan 29 07:56:18 2014 +0100 -+ Signed-off-by: Felix Fietkau - -- mac80211: fix possible memory leak on AP CSA failure -- -- If CSA for AP interface failed and the interface -- was not stopped afterwards another CSA request -- would leak sdata->u.ap.next_beacon. -- -- Signed-off-by: Michal Kazior -- Reviewed-by: Luciano Coelho -- Signed-off-by: Johannes Berg -- --commit 3a77ba08940682bf3d52cf14f980337324af9d4a --Author: Johannes Berg --Date: Sat Feb 1 00:33:29 2014 +0100 -- -- mac80211: fix fragmentation code, particularly for encryption -- -- The "new" fragmentation code (since my rewrite almost 5 years ago) -- erroneously sets skb->len rather than using skb_trim() to adjust -- the length of the first fragment after copying out all the others. -- This leaves the skb tail pointer pointing to after where the data -- originally ended, and thus causes the encryption MIC to be written -- at that point, rather than where it belongs: immediately after the -- data. -- -- The impact of this is that if software encryption is done, then -- a) encryption doesn't work for the first fragment, the connection -- becomes unusable as the first fragment will never be properly -- verified at the receiver, the MIC is practically guaranteed to -- be wrong -- b) we leak up to 8 bytes of plaintext (!) of the packet out into -- the air -- -- This is only mitigated by the fact that many devices are capable -- of doing encryption in hardware, in which case this can't happen -- as the tail pointer is irrelevant in that case. Additionally, -- fragmentation is not used very frequently and would normally have -- to be configured manually. -- -- Fix this by using skb_trim() properly. -- -- Cc: stable@vger.kernel.org -- Fixes: 2de8e0d999b8 ("mac80211: rewrite fragmentation") -- Reported-by: Jouni Malinen -- Signed-off-by: Johannes Berg -- --commit de5f242e0c10e841017e37eb8c38974a642dbca8 --Author: Sujith Manoharan --Date: Tue Jan 28 06:21:59 2014 +0530 -- -- ath9k: Fix build error on ARM -- -- Use mdelay instead of udelay to fix this error: -- -- ERROR: "__bad_udelay" [drivers/net/wireless/ath/ath9k/ath9k_hw.ko] undefined! -- make[1]: *** [__modpost] Error 1 -- make: *** [modules] Error 2 -- -- Reported-by: Josh Boyer -- Signed-off-by: Sujith Manoharan -- --commit 8e3ea7a51dfc61810fcefd947f6edcf61125252a --Author: Geert Uytterhoeven --Date: Sun Jan 26 11:53:21 2014 +0100 -- -- ath9k: Fix uninitialized variable in ath9k_has_tx_pending() -- -- drivers/net/wireless/ath/ath9k/main.c: In function ‘ath9k_has_tx_pending’: -- drivers/net/wireless/ath/ath9k/main.c:1869: warning: ‘npend’ may be used uninitialized in this function -- -- Introduced by commit 10e2318103f5941aa70c318afe34bc41f1b98529 ("ath9k: -- optimize ath9k_flush"). -- -- Signed-off-by: Geert Uytterhoeven -- --commit a4a634a6937ebdd827fa58e8fcdb8ca49a3769f6 --Author: Emmanuel Grumbach --Date: Mon Jan 27 11:07:42 2014 +0200 -- -- mac80211: release the channel in error path in start_ap -- -- When the driver cannot start the AP or when the assignement -- of the beacon goes wrong, we need to unassign the vif. -- -- Cc: stable@vger.kernel.org -- Signed-off-by: Emmanuel Grumbach -- Signed-off-by: Johannes Berg -- --commit dfb6889a75c601aedb7450b7e606668e77da6679 --Author: Johannes Berg --Date: Wed Jan 22 11:14:19 2014 +0200 -- -- cfg80211: send scan results from work queue -- -- Due to the previous commit, when a scan finishes, it is in theory -- possible to hit the following sequence: -- 1. interface starts being removed -- 2. scan is cancelled by driver and cfg80211 is notified -- 3. scan done work is scheduled -- 4. interface is removed completely, rdev->scan_req is freed, -- event sent to userspace but scan done work remains pending -- 5. new scan is requested on another virtual interface -- 6. scan done work runs, freeing the still-running scan -- -- To fix this situation, hang on to the scan done message and block -- new scans while that is the case, and only send the message from -- the work function, regardless of whether the scan_req is already -- freed from interface removal. This makes step 5 above impossible -- and changes step 6 to be -- 5. scan done work runs, sending the scan done message -- -- As this can't work for wext, so we send the message immediately, -- but this shouldn't be an issue since we still return -EBUSY. -- -- Signed-off-by: Johannes Berg -- --commit 45b7ab41fc08627d9a8428cb413d5d84662a9707 --Author: Johannes Berg --Date: Wed Jan 22 11:14:18 2014 +0200 -- -- cfg80211: fix scan done race -- -- When an interface/wdev is removed, any ongoing scan should be -- cancelled by the driver. This will make it call cfg80211, which -- only queues a work struct. If interface/wdev removal is quick -- enough, this can leave the scan request pending and processed -- only after the interface is gone, causing a use-after-free. -- -- Fix this by making sure the scan request is not pending after -- the interface is destroyed. We can't flush or cancel the work -- item due to locking concerns, but when it'll run it shouldn't -- find anything to do. This leaves a potential issue, if a new -- scan gets requested before the work runs, it prematurely stops -- the running scan, potentially causing another crash. I'll fix -- that in the next patch. -- -- This was particularly observed with P2P_DEVICE wdevs, likely -- because freeing them is quicker than freeing netdevs. -- -- Reported-by: Andrei Otcheretianski -- Fixes: 4a58e7c38443 ("cfg80211: don't "leak" uncompleted scans") -- Signed-off-by: Johannes Berg -- --commit ae04fa489ab31b5a10d3cc8399f52761175d4321 --Author: Emmanuel Grumbach --Date: Thu Jan 23 14:28:16 2014 +0200 -- -- mac80211: avoid deadlock revealed by lockdep -- -- sdata->u.ap.request_smps_work can’t be flushed synchronously -- under wdev_lock(wdev) since ieee80211_request_smps_ap_work -- itself locks the same lock. -- While at it, reset the driver_smps_mode when the ap is -- stopped to its default: OFF. -- -- This solves: -- -- ====================================================== -- [ INFO: possible circular locking dependency detected ] -- 3.12.0-ipeer+ #2 Tainted: G O -- ------------------------------------------------------- -- rmmod/2867 is trying to acquire lock: -- ((&sdata->u.ap.request_smps_work)){+.+...}, at: [] flush_work+0x0/0x90 -- -- but task is already holding lock: -- (&wdev->mtx){+.+.+.}, at: [] cfg80211_stop_ap+0x26/0x230 [cfg80211] -- -- which lock already depends on the new lock. -- -- the existing dependency chain (in reverse order) is: -- -- -> #1 (&wdev->mtx){+.+.+.}: -- [] lock_acquire+0x79/0xe0 -- [] mutex_lock_nested+0x4a/0x360 -- [] ieee80211_request_smps_ap_work+0x2b/0x50 [mac80211] -- [] process_one_work+0x198/0x450 -- [] worker_thread+0xf9/0x320 -- [] kthread+0x9f/0xb0 -- [] ret_from_kernel_thread+0x1b/0x28 -- -- -> #0 ((&sdata->u.ap.request_smps_work)){+.+...}: -- [] __lock_acquire+0x183f/0x1910 -- [] lock_acquire+0x79/0xe0 -- [] flush_work+0x47/0x90 -- [] __cancel_work_timer+0x67/0xe0 -- [] cancel_work_sync+0xf/0x20 -- [] ieee80211_stop_ap+0x8c/0x340 [mac80211] -- [] cfg80211_stop_ap+0x8c/0x230 [cfg80211] -- [] cfg80211_leave+0x79/0x100 [cfg80211] -- [] cfg80211_netdev_notifier_call+0xf2/0x4f0 [cfg80211] -- [] notifier_call_chain+0x59/0x130 -- [] __raw_notifier_call_chain+0x1e/0x30 -- [] raw_notifier_call_chain+0x1f/0x30 -- [] call_netdevice_notifiers_info+0x33/0x70 -- [] call_netdevice_notifiers+0x13/0x20 -- [] __dev_close_many+0x34/0xb0 -- [] dev_close_many+0x6e/0xc0 -- [] rollback_registered_many+0xa7/0x1f0 -- [] unregister_netdevice_many+0x14/0x60 -- [] ieee80211_remove_interfaces+0xe9/0x170 [mac80211] -- [] ieee80211_unregister_hw+0x56/0x110 [mac80211] -- [] iwl_op_mode_mvm_stop+0x26/0xe0 [iwlmvm] -- [] _iwl_op_mode_stop+0x3a/0x70 [iwlwifi] -- [] iwl_opmode_deregister+0x6f/0x90 [iwlwifi] -- [] __exit_compat+0xd/0x19 [iwlmvm] -- [] SyS_delete_module+0x179/0x2b0 -- [] sysenter_do_call+0x12/0x32 -- -- Fixes: 687da132234f ("mac80211: implement SMPS for AP") -- Cc: [3.13] -- Reported-by: Ilan Peer -- Signed-off-by: Emmanuel Grumbach -- Signed-off-by: Johannes Berg -- --commit 178b205e96217164fd7c30113464250d0b6f5eca --Author: Johannes Berg --Date: Thu Jan 23 16:32:29 2014 +0100 -- -- cfg80211: re-enable 5/10 MHz support -- -- Unfortunately I forgot this during the merge window, but the -- patch seems small enough to go in as a fix. The userspace API -- bug that was the reason for disabling it has long been fixed. -- -- Signed-off-by: Johannes Berg -- --commit 110a1c79acda14edc83b7c8dc5af9c7ddd23eb61 --Author: Pontus Fuchs --Date: Thu Jan 16 15:00:40 2014 +0100 -- -- nl80211: Reset split_start when netlink skb is exhausted -- -- When the netlink skb is exhausted split_start is left set. In the -- subsequent retry, with a larger buffer, the dump is continued from the -- failing point instead of from the beginning. -- -- This was causing my rt28xx based USB dongle to now show up when -- running "iw list" with an old iw version without split dump support. -- -- Cc: stable@vger.kernel.org -- Fixes: 3713b4e364ef ("nl80211: allow splitting wiphy information in dumps") -- Signed-off-by: Pontus Fuchs -- [avoid the entire workaround when state->split is set] -- Signed-off-by: Johannes Berg -- --commit b4c31b45ffc7ef110fa9ecc34d7878fe7c5b9da4 --Author: Eliad Peller --Date: Sun Jan 12 11:06:37 2014 +0200 -- -- mac80211: move roc cookie assignment earlier -- -- ieee80211_start_roc_work() might add a new roc -- to existing roc, and tell cfg80211 it has already -- started. -- -- However, this might happen before the roc cookie -- was set, resulting in REMAIN_ON_CHANNEL (started) -- event with null cookie. Consequently, it can make -- wpa_supplicant go out of sync. -- -- Fix it by setting the roc cookie earlier. -- -- Cc: stable@vger.kernel.org -- Signed-off-by: Eliad Peller -- Signed-off-by: Johannes Berg -- --commit cfdc9157bfd7bcf88ab4dae08873a9907eba984c --Author: Johannes Berg --Date: Fri Jan 24 14:06:29 2014 +0100 -- -- nl80211: send event when AP operation is stopped -- -- There are a few cases, e.g. suspend, where an AP interface is -- stopped by the kernel rather than by userspace request, most -- commonly when suspending. To let userspace know about this, -- send the NL80211_CMD_STOP_AP command as an event every time -- an AP interface is stopped. This also happens when userspace -- did in fact request the AP stop, but that's not a problem. -- -- For full-MAC drivers this may need to be extended to also -- cover cases where the device stopped the AP operation for -- some reason, this a bit more complicated because then all -- cfg80211 state also needs to be reset; such API is not part -- of this patch. -- -- Signed-off-by: Johannes Berg -- --commit d5d567eda7704f190379ca852a8f9a4112e3eee3 --Author: Johannes Berg --Date: Thu Jan 23 16:20:29 2014 +0100 -- -- mac80211: add length check in ieee80211_is_robust_mgmt_frame() -- -- A few places weren't checking that the frame passed to the -- function actually has enough data even though the function -- clearly documents it must have a payload byte. Make this -- safer by changing the function to take an skb and checking -- the length inside. The old version is preserved for now as -- the rtl* drivers use it and don't have a correct skb. -- -- Signed-off-by: Johannes Berg -- --commit f8f6d212a047fc65c7d3442dfc038f65517236fc --Author: Johannes Berg --Date: Fri Jan 24 10:53:53 2014 +0100 -- -- nl80211: fix scheduled scan RSSI matchset attribute confusion -- -- The scheduled scan matchsets were intended to be a list of filters, -- with the found BSS having to pass at least one of them to be passed -- to the host. When the RSSI attribute was added, however, this was -- broken and currently wpa_supplicant adds that attribute in its own -- matchset; however, it doesn't intend that to mean that anything -- that passes the RSSI filter should be passed to the host, instead -- it wants it to mean that everything needs to also have higher RSSI. -- -- This is semantically problematic because we have a list of filters -- like [ SSID1, SSID2, SSID3, RSSI ] with no real indication which -- one should be OR'ed and which one AND'ed. -- -- To fix this, move the RSSI filter attribute into each matchset. As -- we need to stay backward compatible, treat a matchset with only the -- RSSI attribute as a "default RSSI filter" for all other matchsets, -- but only if there are other matchsets (an RSSI-only matchset by -- itself is still desirable.) -- -- To make driver implementation easier, keep a global min_rssi_thold -- for the entire request as well. The only affected driver is ath6kl. -- -- I found this when I looked into the code after Raja Mani submitted -- a patch fixing the n_match_sets calculation to disregard the RSSI, -- but that patch didn't address the semantic issue. -- -- Reported-by: Raja Mani -- Acked-by: Luciano Coelho -- Signed-off-by: Johannes Berg -- --commit de553e8545e65a6dc4e45f43df7e1443d4291922 --Author: Johannes Berg --Date: Fri Jan 24 10:17:47 2014 +0100 -- -- nl80211: check nla_parse() return values -- -- If there's a policy, then nla_parse() return values must be -- checked, otherwise the policy is useless and there's nothing -- that ensures the attributes are actually what we expect them -- to be. -- -- Signed-off-by: Johannes Berg -- --commit 652204a0733e9e1c54661d6f9d36e2e1e3b22bb1 --Author: Karl Beldan --Date: Thu Jan 23 20:06:34 2014 +0100 -- -- mac80211: send {ADD,DEL}BA on AC_VO like other mgmt frames, as per spec -- -- ATM, {ADD,DEL}BA and BAR frames are sent on the AC matching the TID of -- the BA parameters. In the discussion [1] about this patch, Johannes -- recalled that it fixed some races with the DELBA and indeed this -- behavior was introduced in [2]. -- While [2] is right for the BARs, the part queueing the {ADD,DEL}BAs on -- their BA params TID AC violates the spec and is more a workaround for -- some drivers. Helmut expressed some concerns wrt such drivers, in -- particular DELBAs in rt2x00. -- -- ATM, DELBAs are sent after a driver has called (hence "purposely") -- ieee80211_start_tx_ba_cb_irqsafe and Johannes and Emmanuel gave some -- details wrt intentions behind the split of the IEEE80211_AMPDU_TX_STOP_* -- given to the driver ampdu_action supposed to call this function, which -- could prove handy to people trying to do the right thing in faulty -- drivers (if their fw/hw don't get in their way). -- -- [1] http://mid.gmane.org/1390391564-18481-1-git-send-email-karl.beldan@gmail.com -- [2] Commit: cf6bb79ad828 ("mac80211: Use appropriate TID for sending BAR, ADDBA and DELBA frames") -- -- Signed-off-by: Karl Beldan -- Cc: Helmut Schaa -- Cc: Emmanuel Grumbach -- Signed-off-by: Johannes Berg ----- a/drivers/net/wireless/ath/ath6kl/cfg80211.c --+++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c --@@ -790,7 +790,7 @@ void ath6kl_cfg80211_connect_event(struc -- if (nw_type & ADHOC_NETWORK) { -- ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "ad-hoc %s selected\n", -- nw_type & ADHOC_CREATOR ? "creator" : "joiner"); --- cfg80211_ibss_joined(vif->ndev, bssid, GFP_KERNEL); --+ cfg80211_ibss_joined(vif->ndev, bssid, chan, GFP_KERNEL); -- cfg80211_put_bss(ar->wiphy, bss); -- return; -- } --@@ -861,13 +861,9 @@ void ath6kl_cfg80211_disconnect_event(st -- } -- -- if (vif->nw_type & ADHOC_NETWORK) { --- if (vif->wdev.iftype != NL80211_IFTYPE_ADHOC) { --+ if (vif->wdev.iftype != NL80211_IFTYPE_ADHOC) -- ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, -- "%s: ath6k not in ibss mode\n", __func__); --- return; --- } --- memset(bssid, 0, ETH_ALEN); --- cfg80211_ibss_joined(vif->ndev, bssid, GFP_KERNEL); -- return; -- } -- --@@ -3256,6 +3252,15 @@ static int ath6kl_cfg80211_sscan_start(s -- struct ath6kl_vif *vif = netdev_priv(dev); -- u16 interval; -- int ret, rssi_thold; --+ int n_match_sets = request->n_match_sets; --+ --+ /* --+ * If there's a matchset w/o an SSID, then assume it's just for --+ * the RSSI (nothing else is currently supported) and ignore it. --+ * The device only supports a global RSSI filter that we set below. --+ */ --+ if (n_match_sets == 1 && !request->match_sets[0].ssid.ssid_len) --+ n_match_sets = 0; -- -- if (ar->state != ATH6KL_STATE_ON) -- return -EIO; --@@ -3268,11 +3273,11 @@ static int ath6kl_cfg80211_sscan_start(s -- ret = ath6kl_set_probed_ssids(ar, vif, request->ssids, -- request->n_ssids, -- request->match_sets, --- request->n_match_sets); --+ n_match_sets); -- if (ret < 0) -- return ret; -- --- if (!request->n_match_sets) { --+ if (!n_match_sets) { -- ret = ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx, -- ALL_BSS_FILTER, 0); -- if (ret < 0) --@@ -3286,12 +3291,12 @@ static int ath6kl_cfg80211_sscan_start(s -- -- if (test_bit(ATH6KL_FW_CAPABILITY_RSSI_SCAN_THOLD, -- ar->fw_capabilities)) { --- if (request->rssi_thold <= NL80211_SCAN_RSSI_THOLD_OFF) --+ if (request->min_rssi_thold <= NL80211_SCAN_RSSI_THOLD_OFF) -- rssi_thold = 0; --- else if (request->rssi_thold < -127) --+ else if (request->min_rssi_thold < -127) -- rssi_thold = -127; -- else --- rssi_thold = request->rssi_thold; --+ rssi_thold = request->min_rssi_thold; -- -- ret = ath6kl_wmi_set_rssi_filter_cmd(ar->wmi, vif->fw_vif_idx, -- rssi_thold); ----- a/drivers/net/wireless/ath/ath9k/hw.c --+++ b/drivers/net/wireless/ath/ath9k/hw.c --@@ -1316,7 +1316,7 @@ static bool ath9k_hw_set_reset(struct at -- if (AR_SREV_9300_20_OR_LATER(ah)) -- udelay(50); -- else if (AR_SREV_9100(ah)) --- udelay(10000); --+ mdelay(10); -- else -- udelay(100); -+--- a/drivers/net/wireless/ath/ath9k/recv.c -++++ b/drivers/net/wireless/ath/ath9k/recv.c -+@@ -34,7 +34,8 @@ static inline bool ath9k_check_auto_slee -+ * buffer (or rx fifo). This can incorrectly acknowledge packets -+ * to a sender if last desc is self-linked. -+ */ -+-static void ath_rx_buf_link(struct ath_softc *sc, struct ath_rxbuf *bf) -++static void ath_rx_buf_link(struct ath_softc *sc, struct ath_rxbuf *bf, -++ bool flush) -+ { -+ struct ath_hw *ah = sc->sc_ah; -+ struct ath_common *common = ath9k_hw_common(ah); -+@@ -59,18 +60,19 @@ static void ath_rx_buf_link(struct ath_s -+ common->rx_bufsize, -+ 0); -+ -+- if (sc->rx.rxlink == NULL) -+- ath9k_hw_putrxbuf(ah, bf->bf_daddr); -+- else -++ if (sc->rx.rxlink) -+ *sc->rx.rxlink = bf->bf_daddr; -++ else if (!flush) -++ ath9k_hw_putrxbuf(ah, bf->bf_daddr); -+ -+ sc->rx.rxlink = &ds->ds_link; -+ } - --@@ -1534,7 +1534,7 @@ EXPORT_SYMBOL(ath9k_hw_check_nav); -- bool ath9k_hw_check_alive(struct ath_hw *ah) -+-static void ath_rx_buf_relink(struct ath_softc *sc, struct ath_rxbuf *bf) -++static void ath_rx_buf_relink(struct ath_softc *sc, struct ath_rxbuf *bf, -++ bool flush) - { -- int count = 50; --- u32 reg; --+ u32 reg, last_val; -- -- if (AR_SREV_9300(ah)) -- return !ath9k_hw_detect_mac_hang(ah); --@@ -1542,9 +1542,14 @@ bool ath9k_hw_check_alive(struct ath_hw -- if (AR_SREV_9285_12_OR_LATER(ah)) -- return true; -- --+ last_val = REG_READ(ah, AR_OBS_BUS_1); -- do { -- reg = REG_READ(ah, AR_OBS_BUS_1); --+ if (reg != last_val) --+ return true; -- --+ udelay(1); --+ last_val = reg; -- if ((reg & 0x7E7FFFEF) == 0x00702400) -- continue; -- --@@ -2051,9 +2056,8 @@ static bool ath9k_hw_set_power_awake(str -- -- REG_SET_BIT(ah, AR_RTC_FORCE_WAKE, -- AR_RTC_FORCE_WAKE_EN); --- -- if (AR_SREV_9100(ah)) --- udelay(10000); --+ mdelay(10); -- else -- udelay(50); -+ if (sc->rx.buf_hold) -+- ath_rx_buf_link(sc, sc->rx.buf_hold); -++ ath_rx_buf_link(sc, sc->rx.buf_hold, flush); - ----- a/drivers/net/wireless/ath/ath9k/main.c --+++ b/drivers/net/wireless/ath/ath9k/main.c --@@ -451,7 +451,7 @@ void ath9k_tasklet(unsigned long data) -- * interrupts are enabled in the reset routine. -- */ -- atomic_inc(&ah->intr_ref_cnt); --- ath_dbg(common, ANY, "FATAL: Skipping interrupts\n"); --+ ath_dbg(common, RESET, "FATAL: Skipping interrupts\n"); -- goto out; -+ sc->rx.buf_hold = bf; -+ } -+@@ -442,7 +444,7 @@ int ath_startrecv(struct ath_softc *sc) -+ sc->rx.buf_hold = NULL; -+ sc->rx.rxlink = NULL; -+ list_for_each_entry_safe(bf, tbf, &sc->rx.rxbuf, list) { -+- ath_rx_buf_link(sc, bf); -++ ath_rx_buf_link(sc, bf, false); - } - --@@ -471,7 +471,7 @@ void ath9k_tasklet(unsigned long data) -- * interrupts are enabled in the reset routine. -- */ -- atomic_inc(&ah->intr_ref_cnt); --- ath_dbg(common, ANY, --+ ath_dbg(common, RESET, -- "BB_WATCHDOG: Skipping interrupts\n"); -- goto out; -- } --@@ -484,7 +484,7 @@ void ath9k_tasklet(unsigned long data) -- type = RESET_TYPE_TX_GTT; -- ath9k_queue_reset(sc, type); -- atomic_inc(&ah->intr_ref_cnt); --- ath_dbg(common, ANY, --+ ath_dbg(common, RESET, -- "GTT: Skipping interrupts\n"); -- goto out; -+ /* We could have deleted elements so the list may be empty now */ -+@@ -1118,12 +1120,12 @@ requeue_drop_frag: -+ requeue: -+ list_add_tail(&bf->list, &sc->rx.rxbuf); -+ -+- if (edma) { -+- ath_rx_edma_buf_link(sc, qtype); -+- } else { -+- ath_rx_buf_relink(sc, bf); -++ if (!edma) { -++ ath_rx_buf_relink(sc, bf, flush); -+ if (!flush) -+ ath9k_hw_rxena(ah); -++ } else if (!flush) { -++ ath_rx_edma_buf_link(sc, qtype); - } --@@ -1866,7 +1866,7 @@ static void ath9k_set_coverage_class(str - -- static bool ath9k_has_tx_pending(struct ath_softc *sc) -- { --- int i, npend; --+ int i, npend = 0; -- -- for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) { -- if (!ATH_TXQ_SETUP(sc, i)) ----- a/drivers/net/wireless/iwlwifi/mvm/scan.c --+++ b/drivers/net/wireless/iwlwifi/mvm/scan.c --@@ -595,6 +595,9 @@ static void iwl_scan_offload_build_ssid( -- * config match list. -- */ -- for (i = 0; i < req->n_match_sets && i < PROBE_OPTION_MAX; i++) { --+ /* skip empty SSID matchsets */ --+ if (!req->match_sets[i].ssid.ssid_len) --+ continue; -- scan->direct_scan[i].id = WLAN_EID_SSID; -- scan->direct_scan[i].len = req->match_sets[i].ssid.ssid_len; -- memcpy(scan->direct_scan[i].ssid, req->match_sets[i].ssid.ssid, ----- a/drivers/net/wireless/rtlwifi/rtl8188ee/trx.c --+++ b/drivers/net/wireless/rtlwifi/rtl8188ee/trx.c --@@ -452,7 +452,7 @@ bool rtl88ee_rx_query_desc(struct ieee80 -- /* During testing, hdr was NULL */ -- return false; -- } --- if ((ieee80211_is_robust_mgmt_frame(hdr)) && --+ if ((_ieee80211_is_robust_mgmt_frame(hdr)) && -- (ieee80211_has_protected(hdr->frame_control))) -- rx_status->flag &= ~RX_FLAG_DECRYPTED; -- else ----- a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c --+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c --@@ -393,7 +393,7 @@ bool rtl92ce_rx_query_desc(struct ieee80 -- /* In testing, hdr was NULL here */ -- return false; -- } --- if ((ieee80211_is_robust_mgmt_frame(hdr)) && --+ if ((_ieee80211_is_robust_mgmt_frame(hdr)) && -- (ieee80211_has_protected(hdr->frame_control))) -- rx_status->flag &= ~RX_FLAG_DECRYPTED; -- else ----- a/drivers/net/wireless/rtlwifi/rtl8192se/trx.c --+++ b/drivers/net/wireless/rtlwifi/rtl8192se/trx.c --@@ -310,7 +310,7 @@ bool rtl92se_rx_query_desc(struct ieee80 -- /* during testing, hdr was NULL here */ -- return false; -- } --- if ((ieee80211_is_robust_mgmt_frame(hdr)) && --+ if ((_ieee80211_is_robust_mgmt_frame(hdr)) && -- (ieee80211_has_protected(hdr->frame_control))) -- rx_status->flag &= ~RX_FLAG_DECRYPTED; -- else ----- a/drivers/net/wireless/rtlwifi/rtl8723ae/trx.c --+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/trx.c --@@ -334,7 +334,7 @@ bool rtl8723ae_rx_query_desc(struct ieee -- /* during testing, hdr could be NULL here */ -- return false; -- } --- if ((ieee80211_is_robust_mgmt_frame(hdr)) && --+ if ((_ieee80211_is_robust_mgmt_frame(hdr)) && -- (ieee80211_has_protected(hdr->frame_control))) -- rx_status->flag &= ~RX_FLAG_DECRYPTED; -- else ----- a/include/linux/ieee80211.h --+++ b/include/linux/ieee80211.h --@@ -597,6 +597,20 @@ static inline int ieee80211_is_qos_nullf -- } -+ if (!budget--) -+--- a/net/mac80211/sta_info.c -++++ b/net/mac80211/sta_info.c -+@@ -100,7 +100,8 @@ static void __cleanup_single_sta(struct -+ struct ps_data *ps; - -- /** --+ * ieee80211_is_bufferable_mmpdu - check if frame is bufferable MMPDU --+ * @fc: frame control field in little-endian byteorder --+ */ --+static inline bool ieee80211_is_bufferable_mmpdu(__le16 fc) --+{ --+ /* IEEE 802.11-2012, definition of "bufferable management frame"; --+ * note that this ignores the IBSS special case. */ --+ return ieee80211_is_mgmt(fc) && --+ (ieee80211_is_action(fc) || --+ ieee80211_is_disassoc(fc) || --+ ieee80211_is_deauth(fc)); --+} --+ --+/** -- * ieee80211_is_first_frag - check if IEEE80211_SCTL_FRAG is not set -- * @seq_ctrl: frame sequence control bytes in little-endian byteorder -- */ --@@ -2192,10 +2206,10 @@ static inline u8 *ieee80211_get_DA(struc -- } -+ if (test_sta_flag(sta, WLAN_STA_PS_STA) || -+- test_sta_flag(sta, WLAN_STA_PS_DRIVER)) { -++ test_sta_flag(sta, WLAN_STA_PS_DRIVER) || -++ test_sta_flag(sta, WLAN_STA_PS_DELIVER)) { -+ if (sta->sdata->vif.type == NL80211_IFTYPE_AP || -+ sta->sdata->vif.type == NL80211_IFTYPE_AP_VLAN) -+ ps = &sdata->bss->ps; -+@@ -111,6 +112,7 @@ static void __cleanup_single_sta(struct - -- /** --- * ieee80211_is_robust_mgmt_frame - check if frame is a robust management frame --+ * _ieee80211_is_robust_mgmt_frame - check if frame is a robust management frame -- * @hdr: the frame (buffer must include at least the first octet of payload) -- */ ---static inline bool ieee80211_is_robust_mgmt_frame(struct ieee80211_hdr *hdr) --+static inline bool _ieee80211_is_robust_mgmt_frame(struct ieee80211_hdr *hdr) -- { -- if (ieee80211_is_disassoc(hdr->frame_control) || -- ieee80211_is_deauth(hdr->frame_control)) --@@ -2224,6 +2238,17 @@ static inline bool ieee80211_is_robust_m -- } -+ clear_sta_flag(sta, WLAN_STA_PS_STA); -+ clear_sta_flag(sta, WLAN_STA_PS_DRIVER); -++ clear_sta_flag(sta, WLAN_STA_PS_DELIVER); - -- /** --+ * ieee80211_is_robust_mgmt_frame - check if skb contains a robust mgmt frame --+ * @skb: the skb containing the frame, length will be checked --+ */ --+static inline bool ieee80211_is_robust_mgmt_frame(struct sk_buff *skb) --+{ --+ if (skb->len < 25) --+ return false; --+ return _ieee80211_is_robust_mgmt_frame((void *)skb->data); --+} --+ --+/** -- * ieee80211_is_public_action - check if frame is a public action frame -- * @hdr: the frame -- * @len: length of the frame ----- a/include/net/cfg80211.h --+++ b/include/net/cfg80211.h --@@ -1395,9 +1395,11 @@ struct cfg80211_scan_request { -- * struct cfg80211_match_set - sets of attributes to match -- * -- * @ssid: SSID to be matched --+ * @rssi_thold: don't report scan results below this threshold (in s32 dBm) -- */ -- struct cfg80211_match_set { -- struct cfg80211_ssid ssid; --+ s32 rssi_thold; -- }; -+ atomic_dec(&ps->num_sta_ps); -+ sta_info_recalc_tim(sta); -+@@ -125,7 +127,7 @@ static void __cleanup_single_sta(struct -+ if (ieee80211_vif_is_mesh(&sdata->vif)) -+ mesh_sta_cleanup(sta); - -- /** --@@ -1420,7 +1422,8 @@ struct cfg80211_match_set { -- * @dev: the interface -- * @scan_start: start time of the scheduled scan -- * @channels: channels to scan --- * @rssi_thold: don't report scan results below this threshold (in s32 dBm) --+ * @min_rssi_thold: for drivers only supporting a single threshold, this --+ * contains the minimum over all matchsets -- */ -- struct cfg80211_sched_scan_request { -- struct cfg80211_ssid *ssids; --@@ -1433,7 +1436,7 @@ struct cfg80211_sched_scan_request { -- u32 flags; -- struct cfg80211_match_set *match_sets; -- int n_match_sets; --- s32 rssi_thold; --+ s32 min_rssi_thold; -- -- /* internal */ -- struct wiphy *wiphy; --@@ -3130,8 +3133,8 @@ struct cfg80211_cached_keys; -- * @identifier: (private) Identifier used in nl80211 to identify this -- * wireless device if it has no netdev -- * @current_bss: (private) Used by the internal configuration code --- * @channel: (private) Used by the internal configuration code to track --- * the user-set AP, monitor and WDS channel --+ * @chandef: (private) Used by the internal configuration code to track --+ * the user-set channel definition. -- * @preset_chandef: (private) Used by the internal configuration code to -- * track the channel to be used for AP later -- * @bssid: (private) Used by the internal configuration code --@@ -3195,9 +3198,7 @@ struct wireless_dev { -- -- struct cfg80211_internal_bss *current_bss; /* associated / joined */ -- struct cfg80211_chan_def preset_chandef; --- --- /* for AP and mesh channel tracking */ --- struct ieee80211_channel *channel; --+ struct cfg80211_chan_def chandef; -+- cancel_work_sync(&sta->drv_unblock_wk); -++ cancel_work_sync(&sta->drv_deliver_wk); - -- bool ibss_fixed; -- bool ibss_dfs_possible; --@@ -3879,6 +3880,7 @@ void cfg80211_michael_mic_failure(struct -- * -- * @dev: network device -- * @bssid: the BSSID of the IBSS joined --+ * @channel: the channel of the IBSS joined -- * @gfp: allocation flags -- * -- * This function notifies cfg80211 that the device joined an IBSS or --@@ -3888,7 +3890,8 @@ void cfg80211_michael_mic_failure(struct -- * with the locally generated beacon -- this guarantees that there is -- * always a scan result for this IBSS. cfg80211 will handle the rest. -+ /* -+ * Destroy aggregation state here. It would be nice to wait for the -+@@ -227,6 +229,7 @@ struct sta_info *sta_info_get_by_idx(str - */ ---void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid, gfp_t gfp); --+void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid, --+ struct ieee80211_channel *channel, gfp_t gfp); -- -- /** -- * cfg80211_notify_new_candidate - notify cfg80211 of a new mesh peer candidate ----- a/include/uapi/linux/nl80211.h --+++ b/include/uapi/linux/nl80211.h --@@ -2442,9 +2442,15 @@ enum nl80211_reg_rule_attr { -- * enum nl80211_sched_scan_match_attr - scheduled scan match attributes -- * @__NL80211_SCHED_SCAN_MATCH_ATTR_INVALID: attribute number 0 is reserved -- * @NL80211_SCHED_SCAN_MATCH_ATTR_SSID: SSID to be used for matching, --- * only report BSS with matching SSID. --+ * only report BSS with matching SSID. -- * @NL80211_SCHED_SCAN_MATCH_ATTR_RSSI: RSSI threshold (in dBm) for reporting a --- * BSS in scan results. Filtering is turned off if not specified. --+ * BSS in scan results. Filtering is turned off if not specified. Note that --+ * if this attribute is in a match set of its own, then it is treated as --+ * the default value for all matchsets with an SSID, rather than being a --+ * matchset of its own without an RSSI filter. This is due to problems with --+ * how this API was implemented in the past. Also, due to the same problem, --+ * the only way to create a matchset with only an RSSI filter (with this --+ * attribute) is if there's only a single matchset with the RSSI attribute. -- * @NL80211_SCHED_SCAN_MATCH_ATTR_MAX: highest scheduled scan filter -- * attribute number currently defined -- * @__NL80211_SCHED_SCAN_MATCH_ATTR_AFTER_LAST: internal use ----- a/net/mac80211/agg-tx.c --+++ b/net/mac80211/agg-tx.c --@@ -107,7 +107,7 @@ static void ieee80211_send_addba_request -- mgmt->u.action.u.addba_req.start_seq_num = -- cpu_to_le16(start_seq_num << 4); -- --- ieee80211_tx_skb_tid(sdata, skb, tid); --+ ieee80211_tx_skb(sdata, skb); -- } -- -- void ieee80211_send_bar(struct ieee80211_vif *vif, u8 *ra, u16 tid, u16 ssn) ----- a/net/mac80211/cfg.c --+++ b/net/mac80211/cfg.c --@@ -970,9 +970,9 @@ static int ieee80211_start_ap(struct wip -- /* TODO: make hostapd tell us what it wants */ -- sdata->smps_mode = IEEE80211_SMPS_OFF; -- sdata->needed_rx_chains = sdata->local->rx_chains; --- sdata->radar_required = params->radar_required; -- -- mutex_lock(&local->mtx); --+ sdata->radar_required = params->radar_required; -- err = ieee80211_vif_use_channel(sdata, ¶ms->chandef, -- IEEE80211_CHANCTX_SHARED); -- mutex_unlock(&local->mtx); --@@ -1021,8 +1021,10 @@ static int ieee80211_start_ap(struct wip -- IEEE80211_P2P_OPPPS_ENABLE_BIT; -+ void sta_info_free(struct ieee80211_local *local, struct sta_info *sta) -+ { -++ struct ieee80211_sta_rates *rates; -+ int i; - -- err = ieee80211_assign_beacon(sdata, ¶ms->beacon); --- if (err < 0) --+ if (err < 0) { --+ ieee80211_vif_release_channel(sdata); -- return err; --+ } -- changed |= err; -- -- err = drv_start_ap(sdata->local, sdata); --@@ -1032,6 +1034,7 @@ static int ieee80211_start_ap(struct wip -- if (old) -- kfree_rcu(old, rcu_head); -- RCU_INIT_POINTER(sdata->u.ap.beacon, NULL); --+ ieee80211_vif_release_channel(sdata); -- return err; -+ if (sta->rate_ctrl) -+@@ -238,6 +241,10 @@ void sta_info_free(struct ieee80211_loca -+ kfree(sta->tx_lat); - } - --@@ -1053,6 +1056,7 @@ static int ieee80211_change_beacon(struc -- int err; -- -- sdata = IEEE80211_DEV_TO_SUB_IF(dev); --+ sdata_assert_lock(sdata); -- -- /* don't allow changing the beacon while CSA is in place - offset -- * of channel switch counter may change --@@ -1080,6 +1084,8 @@ static int ieee80211_stop_ap(struct wiph -- struct probe_resp *old_probe_resp; -- struct cfg80211_chan_def chandef; -- --+ sdata_assert_lock(sdata); -++ rates = rcu_dereference_protected(sta->sta.rates, true); -++ if (rates) -++ kfree(rates); - + -- old_beacon = sdata_dereference(sdata->u.ap.beacon, sdata); -- if (!old_beacon) -- return -ENOENT; --@@ -1090,8 +1096,6 @@ static int ieee80211_stop_ap(struct wiph -- kfree(sdata->u.ap.next_beacon); -- sdata->u.ap.next_beacon = NULL; -+ sta_dbg(sta->sdata, "Destroyed STA %pM\n", sta->sta.addr); - --- cancel_work_sync(&sdata->u.ap.request_smps_work); --- -- /* turn off carrier for this interface and dependent VLANs */ -- list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list) -- netif_carrier_off(vlan->dev); --@@ -1103,6 +1107,7 @@ static int ieee80211_stop_ap(struct wiph -- kfree_rcu(old_beacon, rcu_head); -- if (old_probe_resp) -- kfree_rcu(old_probe_resp, rcu_head); --+ sdata->u.ap.driver_smps_mode = IEEE80211_SMPS_OFF; -- -- __sta_info_flush(sdata, true); -- ieee80211_free_keys(sdata, true); --@@ -1988,6 +1993,9 @@ static int ieee80211_change_bss(struct w -- -- band = ieee80211_get_sdata_band(sdata); -- --+ if (WARN_ON(!wiphy->bands[band])) --+ return -EINVAL; --+ -- if (params->use_cts_prot >= 0) { -- sdata->vif.bss_conf.use_cts_prot = params->use_cts_prot; -- changed |= BSS_CHANGED_ERP_CTS_PROT; --@@ -2638,6 +2646,24 @@ static int ieee80211_start_roc_work(stru -- INIT_DELAYED_WORK(&roc->work, ieee80211_sw_roc_work); -- INIT_LIST_HEAD(&roc->dependents); -- --+ /* --+ * cookie is either the roc cookie (for normal roc) --+ * or the SKB (for mgmt TX) --+ */ --+ if (!txskb) { --+ /* local->mtx protects this */ --+ local->roc_cookie_counter++; --+ roc->cookie = local->roc_cookie_counter; --+ /* wow, you wrapped 64 bits ... more likely a bug */ --+ if (WARN_ON(roc->cookie == 0)) { --+ roc->cookie = 1; --+ local->roc_cookie_counter++; --+ } --+ *cookie = roc->cookie; --+ } else { --+ *cookie = (unsigned long)txskb; --+ } --+ -- /* if there's one pending or we're scanning, queue this one */ -- if (!list_empty(&local->roc_list) || -- local->scanning || local->radar_detect_enabled) --@@ -2772,24 +2798,6 @@ static int ieee80211_start_roc_work(stru -- if (!queued) -- list_add_tail(&roc->list, &local->roc_list); -- --- /* --- * cookie is either the roc cookie (for normal roc) --- * or the SKB (for mgmt TX) --- */ --- if (!txskb) { --- /* local->mtx protects this */ --- local->roc_cookie_counter++; --- roc->cookie = local->roc_cookie_counter; --- /* wow, you wrapped 64 bits ... more likely a bug */ --- if (WARN_ON(roc->cookie == 0)) { --- roc->cookie = 1; --- local->roc_cookie_counter++; --- } --- *cookie = roc->cookie; --- } else { --- *cookie = (unsigned long)txskb; --- } --- -- return 0; -+ kfree(sta); -+@@ -252,33 +259,23 @@ static void sta_info_hash_add(struct iee -+ rcu_assign_pointer(local->sta_hash[STA_HASH(sta->sta.addr)], sta); - } - --@@ -3004,8 +3012,10 @@ void ieee80211_csa_finalize_work(struct -- if (!ieee80211_sdata_running(sdata)) -- goto unlock; -- --- sdata->radar_required = sdata->csa_radar_required; --+ sdata_assert_lock(sdata); --+ -- mutex_lock(&local->mtx); --+ sdata->radar_required = sdata->csa_radar_required; -- err = ieee80211_vif_change_channel(sdata, &changed); -- mutex_unlock(&local->mtx); -- if (WARN_ON(err < 0)) --@@ -3022,13 +3032,13 @@ void ieee80211_csa_finalize_work(struct -- switch (sdata->vif.type) { -- case NL80211_IFTYPE_AP: -- err = ieee80211_assign_beacon(sdata, sdata->u.ap.next_beacon); --+ kfree(sdata->u.ap.next_beacon); --+ sdata->u.ap.next_beacon = NULL; --+ -- if (err < 0) -- goto unlock; -- -- changed |= err; --- kfree(sdata->u.ap.next_beacon); --- sdata->u.ap.next_beacon = NULL; --- -- ieee80211_bss_info_change_notify(sdata, err); -- break; -- case NL80211_IFTYPE_ADHOC: --@@ -3066,7 +3076,7 @@ int ieee80211_channel_switch(struct wiph -- struct ieee80211_if_mesh __maybe_unused *ifmsh; -- int err, num_chanctx; -- --- lockdep_assert_held(&sdata->wdev.mtx); --+ sdata_assert_lock(sdata); -- -- if (!list_empty(&local->roc_list) || local->scanning) -- return -EBUSY; ----- a/net/mac80211/ht.c --+++ b/net/mac80211/ht.c --@@ -375,7 +375,7 @@ void ieee80211_send_delba(struct ieee802 -- mgmt->u.action.u.delba.params = cpu_to_le16(params); -- mgmt->u.action.u.delba.reason_code = cpu_to_le16(reason_code); -- --- ieee80211_tx_skb_tid(sdata, skb, tid); --+ ieee80211_tx_skb(sdata, skb); -- } -- -- void ieee80211_process_delba(struct ieee80211_sub_if_data *sdata, --@@ -466,7 +466,9 @@ void ieee80211_request_smps_ap_work(stru -- u.ap.request_smps_work); -- -- sdata_lock(sdata); --- __ieee80211_request_smps_ap(sdata, sdata->u.ap.driver_smps_mode); --+ if (sdata_dereference(sdata->u.ap.beacon, sdata)) --+ __ieee80211_request_smps_ap(sdata, --+ sdata->u.ap.driver_smps_mode); -- sdata_unlock(sdata); -- } -+-static void sta_unblock(struct work_struct *wk) -++static void sta_deliver_ps_frames(struct work_struct *wk) -+ { -+ struct sta_info *sta; - ----- a/net/mac80211/iface.c --+++ b/net/mac80211/iface.c --@@ -770,12 +770,19 @@ static void ieee80211_do_stop(struct iee -+- sta = container_of(wk, struct sta_info, drv_unblock_wk); -++ sta = container_of(wk, struct sta_info, drv_deliver_wk); - -- ieee80211_roc_purge(local, sdata); -+ if (sta->dead) -+ return; - --- if (sdata->vif.type == NL80211_IFTYPE_STATION) --+ switch (sdata->vif.type) { --+ case NL80211_IFTYPE_STATION: -- ieee80211_mgd_stop(sdata); -+- if (!test_sta_flag(sta, WLAN_STA_PS_STA)) { -+- local_bh_disable(); -++ local_bh_disable(); -++ if (!test_sta_flag(sta, WLAN_STA_PS_STA)) -+ ieee80211_sta_ps_deliver_wakeup(sta); -+- local_bh_enable(); -+- } else if (test_and_clear_sta_flag(sta, WLAN_STA_PSPOLL)) { -+- clear_sta_flag(sta, WLAN_STA_PS_DRIVER); - - --- if (sdata->vif.type == NL80211_IFTYPE_ADHOC) --+ break; --+ case NL80211_IFTYPE_ADHOC: -- ieee80211_ibss_stop(sdata); -+- local_bh_disable(); -++ else if (test_and_clear_sta_flag(sta, WLAN_STA_PSPOLL)) -+ ieee80211_sta_ps_deliver_poll_response(sta); -+- local_bh_enable(); -+- } else if (test_and_clear_sta_flag(sta, WLAN_STA_UAPSD)) { -+- clear_sta_flag(sta, WLAN_STA_PS_DRIVER); - - --+ break; --+ case NL80211_IFTYPE_AP: --+ cancel_work_sync(&sdata->u.ap.request_smps_work); --+ break; --+ default: --+ break; --+ } -- -- /* -- * Remove all stations associated with this interface. --@@ -827,7 +834,9 @@ static void ieee80211_do_stop(struct iee -- cancel_work_sync(&local->dynamic_ps_enable_work); -- -- cancel_work_sync(&sdata->recalc_smps); --+ sdata_lock(sdata); -- sdata->vif.csa_active = false; --+ sdata_unlock(sdata); -- cancel_work_sync(&sdata->csa_finalize_work); -- -- cancel_delayed_work_sync(&sdata->dfs_cac_timer_work); ----- a/net/mac80211/rx.c --+++ b/net/mac80211/rx.c --@@ -599,10 +599,10 @@ static int ieee80211_is_unicast_robust_m -- { -- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; -- --- if (skb->len < 24 || is_multicast_ether_addr(hdr->addr1)) --+ if (is_multicast_ether_addr(hdr->addr1)) -- return 0; -- --- return ieee80211_is_robust_mgmt_frame(hdr); --+ return ieee80211_is_robust_mgmt_frame(skb); -+- local_bh_disable(); -++ else if (test_and_clear_sta_flag(sta, WLAN_STA_UAPSD)) -+ ieee80211_sta_ps_deliver_uapsd(sta); -+- local_bh_enable(); -+- } else -+- clear_sta_flag(sta, WLAN_STA_PS_DRIVER); -++ local_bh_enable(); - } - -+ static int sta_prepare_rate_control(struct ieee80211_local *local, -+@@ -340,7 +337,7 @@ struct sta_info *sta_info_alloc(struct i - --@@ -610,10 +610,10 @@ static int ieee80211_is_multicast_robust -- { -- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; -- --- if (skb->len < 24 || !is_multicast_ether_addr(hdr->addr1)) --+ if (!is_multicast_ether_addr(hdr->addr1)) -- return 0; -- --- return ieee80211_is_robust_mgmt_frame(hdr); --+ return ieee80211_is_robust_mgmt_frame(skb); -- } -- -- --@@ -626,7 +626,7 @@ static int ieee80211_get_mmie_keyidx(str -- if (skb->len < 24 + sizeof(*mmie) || !is_multicast_ether_addr(hdr->da)) -- return -1; -- --- if (!ieee80211_is_robust_mgmt_frame((struct ieee80211_hdr *) hdr)) --+ if (!ieee80211_is_robust_mgmt_frame(skb)) -- return -1; /* not a robust management frame */ -- -- mmie = (struct ieee80211_mmie *) --@@ -1128,6 +1128,13 @@ static void sta_ps_end(struct sta_info * -- sta->sta.addr, sta->sta.aid); -- -- if (test_sta_flag(sta, WLAN_STA_PS_DRIVER)) { --+ /* --+ * Clear the flag only if the other one is still set --+ * so that the TX path won't start TX'ing new frames --+ * directly ... In the case that the driver flag isn't --+ * set ieee80211_sta_ps_deliver_wakeup() will clear it. --+ */ --+ clear_sta_flag(sta, WLAN_STA_PS_STA); -- ps_dbg(sta->sdata, "STA %pM aid %d driver-ps-blocked\n", -- sta->sta.addr, sta->sta.aid); -- return; --@@ -1311,18 +1318,15 @@ ieee80211_rx_h_sta_process(struct ieee80 -- !ieee80211_has_morefrags(hdr->frame_control) && -- !(status->rx_flags & IEEE80211_RX_DEFERRED_RELEASE) && -- (rx->sdata->vif.type == NL80211_IFTYPE_AP || --- rx->sdata->vif.type == NL80211_IFTYPE_AP_VLAN)) { --+ rx->sdata->vif.type == NL80211_IFTYPE_AP_VLAN) && --+ /* PM bit is only checked in frames where it isn't reserved, --+ * in AP mode it's reserved in non-bufferable management frames --+ * (cf. IEEE 802.11-2012 8.2.4.1.7 Power Management field) --+ */ --+ (!ieee80211_is_mgmt(hdr->frame_control) || --+ ieee80211_is_bufferable_mmpdu(hdr->frame_control))) { -- if (test_sta_flag(sta, WLAN_STA_PS_STA)) { --- /* --- * Ignore doze->wake transitions that are --- * indicated by non-data frames, the standard --- * is unclear here, but for example going to --- * PS mode and then scanning would cause a --- * doze->wake transition for the probe request, --- * and that is clearly undesirable. --- */ --- if (ieee80211_is_data(hdr->frame_control) && --- !ieee80211_has_pm(hdr->frame_control)) --+ if (!ieee80211_has_pm(hdr->frame_control)) -- sta_ps_end(sta); -- } else { -- if (ieee80211_has_pm(hdr->frame_control)) --@@ -1845,8 +1849,7 @@ static int ieee80211_drop_unencrypted_mg -- * having configured keys. -- */ -- if (unlikely(ieee80211_is_action(fc) && !rx->key && --- ieee80211_is_robust_mgmt_frame( --- (struct ieee80211_hdr *) rx->skb->data))) --+ ieee80211_is_robust_mgmt_frame(rx->skb))) -- return -EACCES; -+ spin_lock_init(&sta->lock); -+ spin_lock_init(&sta->ps_lock); -+- INIT_WORK(&sta->drv_unblock_wk, sta_unblock); -++ INIT_WORK(&sta->drv_deliver_wk, sta_deliver_ps_frames); -+ INIT_WORK(&sta->ampdu_mlme.work, ieee80211_ba_session_work); -+ mutex_init(&sta->ampdu_mlme.mtx); -+ #ifdef CPTCFG_MAC80211_MESH -+@@ -1140,8 +1137,15 @@ void ieee80211_sta_ps_deliver_wakeup(str - } - ----- a/net/mac80211/tx.c --+++ b/net/mac80211/tx.c --@@ -452,8 +452,7 @@ static int ieee80211_use_mfp(__le16 fc, -- if (sta == NULL || !test_sta_flag(sta, WLAN_STA_MFP)) -- return 0; -- --- if (!ieee80211_is_robust_mgmt_frame((struct ieee80211_hdr *) --- skb->data)) --+ if (!ieee80211_is_robust_mgmt_frame(skb)) -- return 0; -- -- return 1; --@@ -478,6 +477,20 @@ ieee80211_tx_h_unicast_ps_buf(struct iee -- sta->sta.addr, sta->sta.aid, ac); -- if (tx->local->total_ps_buffered >= TOTAL_MAX_TX_BUFFER) -- purge_old_ps_buffers(tx->local); -+ ieee80211_add_pending_skbs(local, &pending); -+- clear_sta_flag(sta, WLAN_STA_PS_DRIVER); -+- clear_sta_flag(sta, WLAN_STA_PS_STA); - + --+ /* sync with ieee80211_sta_ps_deliver_wakeup */ --+ spin_lock(&sta->ps_lock); --+ /* --+ * STA woke up the meantime and all the frames on ps_tx_buf have --+ * been queued to pending queue. No reordering can happen, go --+ * ahead and Tx the packet. --+ */ --+ if (!test_sta_flag(sta, WLAN_STA_PS_STA) && --+ !test_sta_flag(sta, WLAN_STA_PS_DRIVER)) { --+ spin_unlock(&sta->ps_lock); --+ return TX_CONTINUE; --+ } -++ /* now we're no longer in the deliver code */ -++ clear_sta_flag(sta, WLAN_STA_PS_DELIVER); - + -- if (skb_queue_len(&sta->ps_tx_buf[ac]) >= STA_MAX_TX_BUFFER) { -- struct sk_buff *old = skb_dequeue(&sta->ps_tx_buf[ac]); -- ps_dbg(tx->sdata, --@@ -492,6 +505,7 @@ ieee80211_tx_h_unicast_ps_buf(struct iee -- info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING; -- info->flags &= ~IEEE80211_TX_TEMPORARY_FLAGS; -- skb_queue_tail(&sta->ps_tx_buf[ac], tx->skb); --+ spin_unlock(&sta->ps_lock); -- -- if (!timer_pending(&local->sta_cleanup)) -- mod_timer(&local->sta_cleanup, --@@ -525,9 +539,7 @@ ieee80211_tx_h_ps_buf(struct ieee80211_t -- -- /* only deauth, disassoc and action are bufferable MMPDUs */ -- if (ieee80211_is_mgmt(hdr->frame_control) && --- !ieee80211_is_deauth(hdr->frame_control) && --- !ieee80211_is_disassoc(hdr->frame_control) && --- !ieee80211_is_action(hdr->frame_control)) { --+ !ieee80211_is_bufferable_mmpdu(hdr->frame_control)) { -- if (tx->flags & IEEE80211_TX_UNICAST) -- info->flags |= IEEE80211_TX_CTL_NO_PS_BUFFER; -- return TX_CONTINUE; --@@ -567,7 +579,7 @@ ieee80211_tx_h_select_key(struct ieee802 -- tx->key = key; -- else if (ieee80211_is_mgmt(hdr->frame_control) && -- is_multicast_ether_addr(hdr->addr1) && --- ieee80211_is_robust_mgmt_frame(hdr) && --+ ieee80211_is_robust_mgmt_frame(tx->skb) && -- (key = rcu_dereference(tx->sdata->default_mgmt_key))) -- tx->key = key; -- else if (is_multicast_ether_addr(hdr->addr1) && --@@ -582,12 +594,12 @@ ieee80211_tx_h_select_key(struct ieee802 -- tx->key = NULL; -- else if (tx->skb->protocol == tx->sdata->control_port_protocol) -- tx->key = NULL; --- else if (ieee80211_is_robust_mgmt_frame(hdr) && --+ else if (ieee80211_is_robust_mgmt_frame(tx->skb) && -- !(ieee80211_is_action(hdr->frame_control) && -- tx->sta && test_sta_flag(tx->sta, WLAN_STA_MFP))) -- tx->key = NULL; -- else if (ieee80211_is_mgmt(hdr->frame_control) && --- !ieee80211_is_robust_mgmt_frame(hdr)) --+ !ieee80211_is_robust_mgmt_frame(tx->skb)) -- tx->key = NULL; -- else { -- I802_DEBUG_INC(tx->local->tx_handlers_drop_unencrypted); --@@ -878,7 +890,7 @@ static int ieee80211_fragment(struct iee -- } -- -- /* adjust first fragment's length */ --- skb->len = hdrlen + per_fragm; --+ skb_trim(skb, hdrlen + per_fragm); -- return 0; -- } -- --@@ -2900,7 +2912,7 @@ ieee80211_get_buffered_bc(struct ieee802 -- cpu_to_le16(IEEE80211_FCTL_MOREDATA); -- } -- --- if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) --+ if (sdata->vif.type == NL80211_IFTYPE_AP) -- sdata = IEEE80211_DEV_TO_SUB_IF(skb->dev); -- if (!ieee80211_tx_prepare(sdata, &tx, skb)) -- break; ----- a/net/mac80211/wpa.c --+++ b/net/mac80211/wpa.c --@@ -499,7 +499,7 @@ ieee80211_crypto_ccmp_decrypt(struct iee -- hdrlen = ieee80211_hdrlen(hdr->frame_control); -- -- if (!ieee80211_is_data(hdr->frame_control) && --- !ieee80211_is_robust_mgmt_frame(hdr)) --+ !ieee80211_is_robust_mgmt_frame(skb)) -- return RX_CONTINUE; -- -- data_len = skb->len - hdrlen - IEEE80211_CCMP_HDR_LEN - ----- a/net/wireless/ap.c --+++ b/net/wireless/ap.c --@@ -27,9 +27,10 @@ static int __cfg80211_stop_ap(struct cfg -- err = rdev_stop_ap(rdev, dev); -- if (!err) { -- wdev->beacon_interval = 0; --- wdev->channel = NULL; --+ memset(&wdev->chandef, 0, sizeof(wdev->chandef)); -- wdev->ssid_len = 0; -- rdev_set_qos_map(rdev, dev, NULL); --+ nl80211_send_ap_stopped(wdev); -- } -++ /* The station might have polled and then woken up before we responded, -++ * so clear these flags now to avoid them sticking around. -++ */ -++ clear_sta_flag(sta, WLAN_STA_PSPOLL); -++ clear_sta_flag(sta, WLAN_STA_UAPSD); -+ spin_unlock(&sta->ps_lock); - -- return err; ----- a/net/wireless/core.c --+++ b/net/wireless/core.c --@@ -203,8 +203,11 @@ void cfg80211_stop_p2p_device(struct cfg -+ atomic_dec(&ps->num_sta_ps); -+@@ -1542,10 +1546,26 @@ void ieee80211_sta_block_awake(struct ie - -- rdev->opencount--; -+ trace_api_sta_block_awake(sta->local, pubsta, block); - --- WARN_ON(rdev->scan_req && rdev->scan_req->wdev == wdev && --- !rdev->scan_req->notified); --+ if (rdev->scan_req && rdev->scan_req->wdev == wdev) { --+ if (WARN_ON(!rdev->scan_req->notified)) --+ rdev->scan_req->aborted = true; --+ ___cfg80211_scan_done(rdev, false); -+- if (block) -++ if (block) { -+ set_sta_flag(sta, WLAN_STA_PS_DRIVER); -+- else if (test_sta_flag(sta, WLAN_STA_PS_DRIVER)) -+- ieee80211_queue_work(hw, &sta->drv_unblock_wk); -++ return; -++ } -++ -++ if (!test_sta_flag(sta, WLAN_STA_PS_DRIVER)) -++ return; -++ -++ if (!test_sta_flag(sta, WLAN_STA_PS_STA)) { -++ set_sta_flag(sta, WLAN_STA_PS_DELIVER); -++ clear_sta_flag(sta, WLAN_STA_PS_DRIVER); -++ ieee80211_queue_work(hw, &sta->drv_deliver_wk); -++ } else if (test_sta_flag(sta, WLAN_STA_PSPOLL) || -++ test_sta_flag(sta, WLAN_STA_UAPSD)) { -++ /* must be asleep in this case */ -++ clear_sta_flag(sta, WLAN_STA_PS_DRIVER); -++ ieee80211_queue_work(hw, &sta->drv_deliver_wk); -++ } else { -++ clear_sta_flag(sta, WLAN_STA_PS_DRIVER); - + } - } -+ EXPORT_SYMBOL(ieee80211_sta_block_awake); - -- static int cfg80211_rfkill_set_block(void *data, bool blocked) --@@ -447,9 +450,6 @@ int wiphy_register(struct wiphy *wiphy) -- int i; -- u16 ifmodes = wiphy->interface_modes; -- --- /* support for 5/10 MHz is broken due to nl80211 API mess - disable */ --- wiphy->flags &= ~WIPHY_FLAG_SUPPORTS_5_10_MHZ; --- -- /* -- * There are major locking problems in nl80211/mac80211 for CSA, -- * disable for all drivers until this has been reworked. --@@ -795,8 +795,6 @@ void cfg80211_leave(struct cfg80211_regi -- default: -- break; -- } --- --- wdev->beacon_interval = 0; -+@@ -1703,3 +1723,137 @@ u8 sta_info_tx_streams(struct sta_info * -+ return ((ht_cap->mcs.tx_params & IEEE80211_HT_MCS_TX_MAX_STREAMS_MASK) -+ >> IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT) + 1; - } -- -- static int cfg80211_netdev_notifier_call(struct notifier_block *nb, --@@ -875,8 +873,11 @@ static int cfg80211_netdev_notifier_call -- break; -- case NETDEV_DOWN: -- cfg80211_update_iface_num(rdev, wdev->iftype, -1); --- WARN_ON(rdev->scan_req && rdev->scan_req->wdev == wdev && --- !rdev->scan_req->notified); --+ if (rdev->scan_req && rdev->scan_req->wdev == wdev) { --+ if (WARN_ON(!rdev->scan_req->notified)) --+ rdev->scan_req->aborted = true; --+ ___cfg80211_scan_done(rdev, false); --+ } -- -- if (WARN_ON(rdev->sched_scan_req && -- rdev->sched_scan_req->dev == wdev->netdev)) { ----- a/net/wireless/core.h --+++ b/net/wireless/core.h --@@ -62,6 +62,7 @@ struct cfg80211_registered_device { -- struct rb_root bss_tree; -- u32 bss_generation; -- struct cfg80211_scan_request *scan_req; /* protected by RTNL */ --+ struct sk_buff *scan_msg; -- struct cfg80211_sched_scan_request *sched_scan_req; -- unsigned long suspend_at; -- struct work_struct scan_done_wk; --@@ -210,6 +211,7 @@ struct cfg80211_event { -- } dc; -- struct { -- u8 bssid[ETH_ALEN]; --+ struct ieee80211_channel *channel; -- } ij; -- }; -- }; --@@ -257,7 +259,8 @@ int __cfg80211_leave_ibss(struct cfg8021 -- struct net_device *dev, bool nowext); -- int cfg80211_leave_ibss(struct cfg80211_registered_device *rdev, -- struct net_device *dev, bool nowext); ---void __cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid); --+void __cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid, --+ struct ieee80211_channel *channel); -- int cfg80211_ibss_wext_join(struct cfg80211_registered_device *rdev, -- struct wireless_dev *wdev); -- --@@ -361,7 +364,8 @@ int cfg80211_validate_key_settings(struc -- struct key_params *params, int key_idx, -- bool pairwise, const u8 *mac_addr); -- void __cfg80211_scan_done(struct work_struct *wk); ---void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev); --+void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev, --+ bool send_message); -- void __cfg80211_sched_scan_results(struct work_struct *wk); -- int __cfg80211_stop_sched_scan(struct cfg80211_registered_device *rdev, -- bool driver_initiated); --@@ -441,7 +445,8 @@ static inline unsigned int elapsed_jiffi -- void -- cfg80211_get_chan_state(struct wireless_dev *wdev, -- struct ieee80211_channel **chan, --- enum cfg80211_chan_mode *chanmode); --+ enum cfg80211_chan_mode *chanmode, --+ u8 *radar_detect); -- -- int cfg80211_set_monitor_channel(struct cfg80211_registered_device *rdev, -- struct cfg80211_chan_def *chandef); ----- a/net/wireless/nl80211.c --+++ b/net/wireless/nl80211.c --@@ -1723,9 +1723,10 @@ static int nl80211_dump_wiphy(struct sk_ -- * We can then retry with the larger buffer. -- */ -- if ((ret == -ENOBUFS || ret == -EMSGSIZE) && --- !skb->len && --+ !skb->len && !state->split && -- cb->min_dump_alloc < 4096) { -- cb->min_dump_alloc = 4096; --+ state->split_start = 0; -- rtnl_unlock(); -- return 1; -- } --@@ -2047,10 +2048,12 @@ static int nl80211_set_wiphy(struct sk_b -- nla_for_each_nested(nl_txq_params, -- info->attrs[NL80211_ATTR_WIPHY_TXQ_PARAMS], -- rem_txq_params) { --- nla_parse(tb, NL80211_TXQ_ATTR_MAX, --- nla_data(nl_txq_params), --- nla_len(nl_txq_params), --- txq_params_policy); --+ result = nla_parse(tb, NL80211_TXQ_ATTR_MAX, --+ nla_data(nl_txq_params), --+ nla_len(nl_txq_params), --+ txq_params_policy); --+ if (result) --+ goto bad_res; -- result = parse_txq_params(tb, &txq_params); -- if (result) -- goto bad_res; --@@ -3289,7 +3292,7 @@ static int nl80211_start_ap(struct sk_bu -- if (!err) { -- wdev->preset_chandef = params.chandef; -- wdev->beacon_interval = params.beacon_interval; --- wdev->channel = params.chandef.chan; --+ wdev->chandef = params.chandef; -- wdev->ssid_len = params.ssid_len; -- memcpy(wdev->ssid, params.ssid, wdev->ssid_len); -- } --@@ -5210,9 +5213,11 @@ static int nl80211_set_reg(struct sk_buf -- -- nla_for_each_nested(nl_reg_rule, info->attrs[NL80211_ATTR_REG_RULES], -- rem_reg_rules) { --- nla_parse(tb, NL80211_REG_RULE_ATTR_MAX, --- nla_data(nl_reg_rule), nla_len(nl_reg_rule), --- reg_rule_policy); --+ r = nla_parse(tb, NL80211_REG_RULE_ATTR_MAX, --+ nla_data(nl_reg_rule), nla_len(nl_reg_rule), --+ reg_rule_policy); --+ if (r) --+ goto bad_reg; -- r = parse_reg_rule(tb, &rd->reg_rules[rule_idx]); -- if (r) -- goto bad_reg; --@@ -5277,7 +5282,7 @@ static int nl80211_trigger_scan(struct s -- if (!rdev->ops->scan) -- return -EOPNOTSUPP; -- --- if (rdev->scan_req) { --+ if (rdev->scan_req || rdev->scan_msg) { -- err = -EBUSY; -- goto unlock; -- } --@@ -5475,6 +5480,7 @@ static int nl80211_start_sched_scan(stru -- enum ieee80211_band band; -- size_t ie_len; -- struct nlattr *tb[NL80211_SCHED_SCAN_MATCH_ATTR_MAX + 1]; --+ s32 default_match_rssi = NL80211_SCAN_RSSI_THOLD_OFF; -- -- if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN) || -- !rdev->ops->sched_scan_start) --@@ -5509,11 +5515,40 @@ static int nl80211_start_sched_scan(stru -- if (n_ssids > wiphy->max_sched_scan_ssids) -- return -EINVAL; -- --- if (info->attrs[NL80211_ATTR_SCHED_SCAN_MATCH]) --+ /* --+ * First, count the number of 'real' matchsets. Due to an issue with --+ * the old implementation, matchsets containing only the RSSI attribute --+ * (NL80211_SCHED_SCAN_MATCH_ATTR_RSSI) are considered as the 'default' --+ * RSSI for all matchsets, rather than their own matchset for reporting --+ * all APs with a strong RSSI. This is needed to be compatible with --+ * older userspace that treated a matchset with only the RSSI as the --+ * global RSSI for all other matchsets - if there are other matchsets. --+ */ --+ if (info->attrs[NL80211_ATTR_SCHED_SCAN_MATCH]) { -- nla_for_each_nested(attr, -- info->attrs[NL80211_ATTR_SCHED_SCAN_MATCH], --- tmp) --- n_match_sets++; --+ tmp) { --+ struct nlattr *rssi; - + --+ err = nla_parse(tb, NL80211_SCHED_SCAN_MATCH_ATTR_MAX, --+ nla_data(attr), nla_len(attr), --+ nl80211_match_policy); --+ if (err) --+ return err; --+ /* add other standalone attributes here */ --+ if (tb[NL80211_SCHED_SCAN_MATCH_ATTR_SSID]) { --+ n_match_sets++; --+ continue; --+ } --+ rssi = tb[NL80211_SCHED_SCAN_MATCH_ATTR_RSSI]; --+ if (rssi) --+ default_match_rssi = nla_get_s32(rssi); -++void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) -++{ -++ struct ieee80211_sub_if_data *sdata = sta->sdata; -++ struct ieee80211_local *local = sdata->local; -++ struct rate_control_ref *ref = local->rate_ctrl; -++ struct timespec uptime; -++ u64 packets = 0; -++ u32 thr = 0; -++ int i, ac; -++ -++ sinfo->generation = sdata->local->sta_generation; -++ -++ sinfo->filled = STATION_INFO_INACTIVE_TIME | -++ STATION_INFO_RX_BYTES64 | -++ STATION_INFO_TX_BYTES64 | -++ STATION_INFO_RX_PACKETS | -++ STATION_INFO_TX_PACKETS | -++ STATION_INFO_TX_RETRIES | -++ STATION_INFO_TX_FAILED | -++ STATION_INFO_TX_BITRATE | -++ STATION_INFO_RX_BITRATE | -++ STATION_INFO_RX_DROP_MISC | -++ STATION_INFO_BSS_PARAM | -++ STATION_INFO_CONNECTED_TIME | -++ STATION_INFO_STA_FLAGS | -++ STATION_INFO_BEACON_LOSS_COUNT; -++ -++ do_posix_clock_monotonic_gettime(&uptime); -++ sinfo->connected_time = uptime.tv_sec - sta->last_connected; -++ -++ sinfo->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx); -++ sinfo->tx_bytes = 0; -++ for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { -++ sinfo->tx_bytes += sta->tx_bytes[ac]; -++ packets += sta->tx_packets[ac]; -++ } -++ sinfo->tx_packets = packets; -++ sinfo->rx_bytes = sta->rx_bytes; -++ sinfo->rx_packets = sta->rx_packets; -++ sinfo->tx_retries = sta->tx_retry_count; -++ sinfo->tx_failed = sta->tx_retry_failed; -++ sinfo->rx_dropped_misc = sta->rx_dropped; -++ sinfo->beacon_loss_count = sta->beacon_loss_count; -++ -++ if ((sta->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) || -++ (sta->local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC)) { -++ sinfo->filled |= STATION_INFO_SIGNAL | STATION_INFO_SIGNAL_AVG; -++ if (!local->ops->get_rssi || -++ drv_get_rssi(local, sdata, &sta->sta, &sinfo->signal)) -++ sinfo->signal = (s8)sta->last_signal; -++ sinfo->signal_avg = (s8) -ewma_read(&sta->avg_signal); -++ } -++ if (sta->chains) { -++ sinfo->filled |= STATION_INFO_CHAIN_SIGNAL | -++ STATION_INFO_CHAIN_SIGNAL_AVG; -++ -++ sinfo->chains = sta->chains; -++ for (i = 0; i < ARRAY_SIZE(sinfo->chain_signal); i++) { -++ sinfo->chain_signal[i] = sta->chain_signal_last[i]; -++ sinfo->chain_signal_avg[i] = -++ (s8) -ewma_read(&sta->chain_signal_avg[i]); - + } - + } - + --+ /* However, if there's no other matchset, add the RSSI one */ --+ if (!n_match_sets && default_match_rssi != NL80211_SCAN_RSSI_THOLD_OFF) --+ n_match_sets = 1; -- -- if (n_match_sets > wiphy->max_match_sets) -- return -EINVAL; --@@ -5634,11 +5669,22 @@ static int nl80211_start_sched_scan(stru -- tmp) { -- struct nlattr *ssid, *rssi; -- --- nla_parse(tb, NL80211_SCHED_SCAN_MATCH_ATTR_MAX, --- nla_data(attr), nla_len(attr), --- nl80211_match_policy); --+ err = nla_parse(tb, NL80211_SCHED_SCAN_MATCH_ATTR_MAX, --+ nla_data(attr), nla_len(attr), --+ nl80211_match_policy); --+ if (err) --+ goto out_free; -- ssid = tb[NL80211_SCHED_SCAN_MATCH_ATTR_SSID]; -- if (ssid) { --+ if (WARN_ON(i >= n_match_sets)) { --+ /* this indicates a programming error, --+ * the loop above should have verified --+ * things properly --+ */ --+ err = -EINVAL; --+ goto out_free; --+ } --+ -- if (nla_len(ssid) > IEEE80211_MAX_SSID_LEN) { -- err = -EINVAL; -- goto out_free; --@@ -5647,15 +5693,28 @@ static int nl80211_start_sched_scan(stru -- nla_data(ssid), nla_len(ssid)); -- request->match_sets[i].ssid.ssid_len = -- nla_len(ssid); --+ /* special attribute - old implemenation w/a */ --+ request->match_sets[i].rssi_thold = --+ default_match_rssi; --+ rssi = tb[NL80211_SCHED_SCAN_MATCH_ATTR_RSSI]; --+ if (rssi) --+ request->match_sets[i].rssi_thold = --+ nla_get_s32(rssi); -- } --- rssi = tb[NL80211_SCHED_SCAN_MATCH_ATTR_RSSI]; --- if (rssi) --- request->rssi_thold = nla_get_u32(rssi); --- else --- request->rssi_thold = --- NL80211_SCAN_RSSI_THOLD_OFF; -- i++; -- } --+ --+ /* there was no other matchset, so the RSSI one is alone */ --+ if (i == 0) --+ request->match_sets[0].rssi_thold = default_match_rssi; -++ sta_set_rate_info_tx(sta, &sta->last_tx_rate, &sinfo->txrate); -++ sta_set_rate_info_rx(sta, &sinfo->rxrate); -++ -++ if (ieee80211_vif_is_mesh(&sdata->vif)) { -++#ifdef CPTCFG_MAC80211_MESH -++ sinfo->filled |= STATION_INFO_LLID | -++ STATION_INFO_PLID | -++ STATION_INFO_PLINK_STATE | -++ STATION_INFO_LOCAL_PM | -++ STATION_INFO_PEER_PM | -++ STATION_INFO_NONPEER_PM; -++ -++ sinfo->llid = sta->llid; -++ sinfo->plid = sta->plid; -++ sinfo->plink_state = sta->plink_state; -++ if (test_sta_flag(sta, WLAN_STA_TOFFSET_KNOWN)) { -++ sinfo->filled |= STATION_INFO_T_OFFSET; -++ sinfo->t_offset = sta->t_offset; -++ } -++ sinfo->local_pm = sta->local_pm; -++ sinfo->peer_pm = sta->peer_pm; -++ sinfo->nonpeer_pm = sta->nonpeer_pm; -++#endif -++ } - + --+ request->min_rssi_thold = INT_MAX; --+ for (i = 0; i < n_match_sets; i++) --+ request->min_rssi_thold = --+ min(request->match_sets[i].rssi_thold, --+ request->min_rssi_thold); --+ } else { --+ request->min_rssi_thold = NL80211_SCAN_RSSI_THOLD_OFF; -- } -- -- if (info->attrs[NL80211_ATTR_IE]) { --@@ -5751,7 +5810,7 @@ static int nl80211_start_radar_detection -- -- err = rdev->ops->start_radar_detection(&rdev->wiphy, dev, &chandef); -- if (!err) { --- wdev->channel = chandef.chan; --+ wdev->chandef = chandef; -- wdev->cac_started = true; -- wdev->cac_start_time = jiffies; -- } --@@ -7502,16 +7561,19 @@ static int nl80211_set_tx_bitrate_mask(s -- * directly to the enum ieee80211_band values used in cfg80211. -- */ -- BUILD_BUG_ON(NL80211_MAX_SUPP_HT_RATES > IEEE80211_HT_MCS_MASK_LEN * 8); --- nla_for_each_nested(tx_rates, info->attrs[NL80211_ATTR_TX_RATES], rem) --- { --+ nla_for_each_nested(tx_rates, info->attrs[NL80211_ATTR_TX_RATES], rem) { -- enum ieee80211_band band = nla_type(tx_rates); --+ int err; -++ sinfo->bss_param.flags = 0; -++ if (sdata->vif.bss_conf.use_cts_prot) -++ sinfo->bss_param.flags |= BSS_PARAM_FLAGS_CTS_PROT; -++ if (sdata->vif.bss_conf.use_short_preamble) -++ sinfo->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_PREAMBLE; -++ if (sdata->vif.bss_conf.use_short_slot) -++ sinfo->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_SLOT_TIME; -++ sinfo->bss_param.dtim_period = sdata->local->hw.conf.ps_dtim_period; -++ sinfo->bss_param.beacon_interval = sdata->vif.bss_conf.beacon_int; -++ -++ sinfo->sta_flags.set = 0; -++ sinfo->sta_flags.mask = BIT(NL80211_STA_FLAG_AUTHORIZED) | -++ BIT(NL80211_STA_FLAG_SHORT_PREAMBLE) | -++ BIT(NL80211_STA_FLAG_WME) | -++ BIT(NL80211_STA_FLAG_MFP) | -++ BIT(NL80211_STA_FLAG_AUTHENTICATED) | -++ BIT(NL80211_STA_FLAG_ASSOCIATED) | -++ BIT(NL80211_STA_FLAG_TDLS_PEER); -++ if (test_sta_flag(sta, WLAN_STA_AUTHORIZED)) -++ sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_AUTHORIZED); -++ if (test_sta_flag(sta, WLAN_STA_SHORT_PREAMBLE)) -++ sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_SHORT_PREAMBLE); -++ if (test_sta_flag(sta, WLAN_STA_WME)) -++ sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_WME); -++ if (test_sta_flag(sta, WLAN_STA_MFP)) -++ sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_MFP); -++ if (test_sta_flag(sta, WLAN_STA_AUTH)) -++ sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_AUTHENTICATED); -++ if (test_sta_flag(sta, WLAN_STA_ASSOC)) -++ sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_ASSOCIATED); -++ if (test_sta_flag(sta, WLAN_STA_TDLS_PEER)) -++ sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_TDLS_PEER); -++ -++ /* check if the driver has a SW RC implementation */ -++ if (ref && ref->ops->get_expected_throughput) -++ thr = ref->ops->get_expected_throughput(sta->rate_ctrl_priv); -++ else -++ thr = drv_get_expected_throughput(local, &sta->sta); - + -- if (band < 0 || band >= IEEE80211_NUM_BANDS) -- return -EINVAL; -- sband = rdev->wiphy.bands[band]; -- if (sband == NULL) -- return -EINVAL; --- nla_parse(tb, NL80211_TXRATE_MAX, nla_data(tx_rates), --- nla_len(tx_rates), nl80211_txattr_policy); --+ err = nla_parse(tb, NL80211_TXRATE_MAX, nla_data(tx_rates), --+ nla_len(tx_rates), nl80211_txattr_policy); --+ if (err) --+ return err; -- if (tb[NL80211_TXRATE_LEGACY]) { -- mask.control[band].legacy = rateset_to_mask( -- sband, --@@ -10054,40 +10116,31 @@ void nl80211_send_scan_start(struct cfg8 -- NL80211_MCGRP_SCAN, GFP_KERNEL); -- } -- ---void nl80211_send_scan_done(struct cfg80211_registered_device *rdev, --- struct wireless_dev *wdev) --+struct sk_buff *nl80211_build_scan_msg(struct cfg80211_registered_device *rdev, --+ struct wireless_dev *wdev, bool aborted) -- { -- struct sk_buff *msg; -- -- msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); -- if (!msg) --- return; --+ return NULL; -- -- if (nl80211_send_scan_msg(msg, rdev, wdev, 0, 0, 0, --- NL80211_CMD_NEW_SCAN_RESULTS) < 0) { --+ aborted ? NL80211_CMD_SCAN_ABORTED : --+ NL80211_CMD_NEW_SCAN_RESULTS) < 0) { -- nlmsg_free(msg); --- return; --+ return NULL; -- } -- --- genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, --- NL80211_MCGRP_SCAN, GFP_KERNEL); --+ return msg; -- } -- ---void nl80211_send_scan_aborted(struct cfg80211_registered_device *rdev, --- struct wireless_dev *wdev) --+void nl80211_send_scan_result(struct cfg80211_registered_device *rdev, --+ struct sk_buff *msg) -- { --- struct sk_buff *msg; --- --- msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); -- if (!msg) -- return; -- --- if (nl80211_send_scan_msg(msg, rdev, wdev, 0, 0, 0, --- NL80211_CMD_SCAN_ABORTED) < 0) { --- nlmsg_free(msg); --- return; --- } --- -- genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, -- NL80211_MCGRP_SCAN, GFP_KERNEL); -- } --@@ -11158,7 +11211,8 @@ void cfg80211_ch_switch_notify(struct ne -- wdev->iftype != NL80211_IFTYPE_MESH_POINT)) -- return; -- --- wdev->channel = chandef->chan; --+ wdev->chandef = *chandef; --+ wdev->preset_chandef = *chandef; -- nl80211_ch_switch_notify(rdev, dev, chandef, GFP_KERNEL); -- } -- EXPORT_SYMBOL(cfg80211_ch_switch_notify); --@@ -11673,6 +11727,35 @@ void cfg80211_crit_proto_stopped(struct -- } -- EXPORT_SYMBOL(cfg80211_crit_proto_stopped); -++ if (thr != 0) { -++ sinfo->filled |= STATION_INFO_EXPECTED_THROUGHPUT; -++ sinfo->expected_throughput = thr; -++ } -++} -+--- a/net/mac80211/status.c -++++ b/net/mac80211/status.c -+@@ -541,6 +541,23 @@ static void ieee80211_tx_latency_end_msr -+ */ -+ #define STA_LOST_PKT_THRESHOLD 50 - --+void nl80211_send_ap_stopped(struct wireless_dev *wdev) -++static void ieee80211_lost_packet(struct sta_info *sta, struct sk_buff *skb) - +{ --+ struct wiphy *wiphy = wdev->wiphy; --+ struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); --+ struct sk_buff *msg; --+ void *hdr; -++ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); - + --+ msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); --+ if (!msg) -++ /* This packet was aggregated but doesn't carry status info */ -++ if ((info->flags & IEEE80211_TX_CTL_AMPDU) && -++ !(info->flags & IEEE80211_TX_STAT_AMPDU)) - + return; - + --+ hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_STOP_AP); --+ if (!hdr) --+ goto out; --+ --+ if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) || --+ nla_put_u32(msg, NL80211_ATTR_IFINDEX, wdev->netdev->ifindex) || --+ nla_put_u64(msg, NL80211_ATTR_WDEV, wdev_id(wdev))) --+ goto out; --+ --+ genlmsg_end(msg, hdr); -++ if (++sta->lost_packets < STA_LOST_PKT_THRESHOLD) -++ return; - + --+ genlmsg_multicast_netns(&nl80211_fam, wiphy_net(wiphy), msg, 0, --+ NL80211_MCGRP_MLME, GFP_KERNEL); --+ return; --+ out: --+ nlmsg_free(msg); -++ cfg80211_cqm_pktloss_notify(sta->sdata->dev, sta->sta.addr, -++ sta->lost_packets, GFP_ATOMIC); -++ sta->lost_packets = 0; - +} - + -- /* initialisation/exit functions */ -- -- int nl80211_init(void) ----- a/net/wireless/nl80211.h --+++ b/net/wireless/nl80211.h --@@ -8,10 +8,10 @@ void nl80211_exit(void); -- void nl80211_notify_dev_rename(struct cfg80211_registered_device *rdev); -- void nl80211_send_scan_start(struct cfg80211_registered_device *rdev, -- struct wireless_dev *wdev); ---void nl80211_send_scan_done(struct cfg80211_registered_device *rdev, --- struct wireless_dev *wdev); ---void nl80211_send_scan_aborted(struct cfg80211_registered_device *rdev, --- struct wireless_dev *wdev); --+struct sk_buff *nl80211_build_scan_msg(struct cfg80211_registered_device *rdev, --+ struct wireless_dev *wdev, bool aborted); --+void nl80211_send_scan_result(struct cfg80211_registered_device *rdev, --+ struct sk_buff *msg); -- void nl80211_send_sched_scan(struct cfg80211_registered_device *rdev, -- struct net_device *netdev, u32 cmd); -- void nl80211_send_sched_scan_results(struct cfg80211_registered_device *rdev, --@@ -74,6 +74,8 @@ nl80211_radar_notify(struct cfg80211_reg -- enum nl80211_radar_event event, -- struct net_device *netdev, gfp_t gfp); -- --+void nl80211_send_ap_stopped(struct wireless_dev *wdev); --+ -- void cfg80211_rdev_free_coalesce(struct cfg80211_registered_device *rdev); -- -- #endif /* __NET_WIRELESS_NL80211_H */ ----- a/net/wireless/scan.c --+++ b/net/wireless/scan.c --@@ -161,18 +161,25 @@ static void __cfg80211_bss_expire(struct -- dev->bss_generation++; -- } -- ---void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev) --+void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev, --+ bool send_message) -+ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) - { -- struct cfg80211_scan_request *request; -- struct wireless_dev *wdev; --+ struct sk_buff *msg; -- #ifdef CPTCFG_CFG80211_WEXT -- union iwreq_data wrqu; -- #endif -- -- ASSERT_RTNL(); -- --- request = rdev->scan_req; --+ if (rdev->scan_msg) { --+ nl80211_send_scan_result(rdev, rdev->scan_msg); --+ rdev->scan_msg = NULL; --+ return; --+ } -+ struct sk_buff *skb2; -+@@ -680,12 +697,8 @@ void ieee80211_tx_status(struct ieee8021 -+ if (info->flags & IEEE80211_TX_STAT_ACK) { -+ if (sta->lost_packets) -+ sta->lost_packets = 0; -+- } else if (++sta->lost_packets >= STA_LOST_PKT_THRESHOLD) { -+- cfg80211_cqm_pktloss_notify(sta->sdata->dev, -+- sta->sta.addr, -+- sta->lost_packets, -+- GFP_ATOMIC); -+- sta->lost_packets = 0; -++ } else { -++ ieee80211_lost_packet(sta, skb); -+ } -+ } - --+ request = rdev->scan_req; -- if (!request) -+--- a/net/mac80211/rx.c -++++ b/net/mac80211/rx.c -+@@ -1107,6 +1107,8 @@ static void sta_ps_end(struct sta_info * - return; -- --@@ -186,18 +193,16 @@ void ___cfg80211_scan_done(struct cfg802 -- if (wdev->netdev) -- cfg80211_sme_scan_done(wdev->netdev); -- --- if (request->aborted) { --- nl80211_send_scan_aborted(rdev, wdev); --- } else { --- if (request->flags & NL80211_SCAN_FLAG_FLUSH) { --- /* flush entries from previous scans */ --- spin_lock_bh(&rdev->bss_lock); --- __cfg80211_bss_expire(rdev, request->scan_start); --- spin_unlock_bh(&rdev->bss_lock); --- } --- nl80211_send_scan_done(rdev, wdev); --+ if (!request->aborted && --+ request->flags & NL80211_SCAN_FLAG_FLUSH) { --+ /* flush entries from previous scans */ --+ spin_lock_bh(&rdev->bss_lock); --+ __cfg80211_bss_expire(rdev, request->scan_start); --+ spin_unlock_bh(&rdev->bss_lock); - } - --+ msg = nl80211_build_scan_msg(rdev, wdev, request->aborted); --+ -- #ifdef CPTCFG_CFG80211_WEXT -- if (wdev->netdev && !request->aborted) { -- memset(&wrqu, 0, sizeof(wrqu)); --@@ -211,6 +216,11 @@ void ___cfg80211_scan_done(struct cfg802 -- -- rdev->scan_req = NULL; -- kfree(request); --+ --+ if (!send_message) --+ rdev->scan_msg = msg; --+ else --+ nl80211_send_scan_result(rdev, msg); -++ set_sta_flag(sta, WLAN_STA_PS_DELIVER); -++ clear_sta_flag(sta, WLAN_STA_PS_STA); -+ ieee80211_sta_ps_deliver_wakeup(sta); - } - -- void __cfg80211_scan_done(struct work_struct *wk) --@@ -221,7 +231,7 @@ void __cfg80211_scan_done(struct work_st -- scan_done_wk); -+--- a/net/mac80211/sta_info.h -++++ b/net/mac80211/sta_info.h -+@@ -82,6 +82,7 @@ enum ieee80211_sta_info_flags { -+ WLAN_STA_TOFFSET_KNOWN, -+ WLAN_STA_MPSP_OWNER, -+ WLAN_STA_MPSP_RECIPIENT, -++ WLAN_STA_PS_DELIVER, -+ }; - -- rtnl_lock(); --- ___cfg80211_scan_done(rdev); --+ ___cfg80211_scan_done(rdev, true); -- rtnl_unlock(); -- } -+ #define ADDBA_RESP_INTERVAL HZ -+@@ -265,7 +266,7 @@ struct ieee80211_tx_latency_stat { -+ * @last_rx_rate_vht_nss: rx status nss of last data packet -+ * @lock: used for locking all fields that require locking, see comments -+ * in the header file. -+- * @drv_unblock_wk: used for driver PS unblocking -++ * @drv_deliver_wk: used for delivering frames after driver PS unblocking -+ * @listen_interval: listen interval of this station, when we're acting as AP -+ * @_flags: STA flags, see &enum ieee80211_sta_info_flags, do not use directly -+ * @ps_lock: used for powersave (when mac80211 is the AP) related locking -+@@ -278,7 +279,6 @@ struct ieee80211_tx_latency_stat { -+ * @driver_buffered_tids: bitmap of TIDs the driver has data buffered on -+ * @rx_packets: Number of MSDUs received from this STA -+ * @rx_bytes: Number of bytes received from this STA -+- * @wep_weak_iv_count: number of weak WEP IVs received from this station -+ * @last_rx: time (in jiffies) when last frame was received from this STA -+ * @last_connected: time (in seconds) when a station got connected -+ * @num_duplicates: number of duplicate frames received from this STA -+@@ -345,7 +345,7 @@ struct sta_info { -+ void *rate_ctrl_priv; -+ spinlock_t lock; -+ -+- struct work_struct drv_unblock_wk; -++ struct work_struct drv_deliver_wk; -+ -+ u16 listen_interval; -+ -+@@ -367,7 +367,6 @@ struct sta_info { -+ /* Updated from RX path only, no locking requirements */ -+ unsigned long rx_packets; -+ u64 rx_bytes; -+- unsigned long wep_weak_iv_count; -+ unsigned long last_rx; -+ long last_connected; -+ unsigned long num_duplicates; -+@@ -628,6 +627,8 @@ void sta_set_rate_info_tx(struct sta_inf -+ struct rate_info *rinfo); -+ void sta_set_rate_info_rx(struct sta_info *sta, -+ struct rate_info *rinfo); -++void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo); -++ -+ void ieee80211_sta_expire(struct ieee80211_sub_if_data *sdata, -+ unsigned long exp_time); -+ u8 sta_info_tx_streams(struct sta_info *sta); -+--- a/net/mac80211/tx.c -++++ b/net/mac80211/tx.c -+@@ -469,7 +469,8 @@ ieee80211_tx_h_unicast_ps_buf(struct iee -+ return TX_CONTINUE; - --@@ -1079,7 +1089,7 @@ int cfg80211_wext_siwscan(struct net_dev -- if (IS_ERR(rdev)) -- return PTR_ERR(rdev); -+ if (unlikely((test_sta_flag(sta, WLAN_STA_PS_STA) || -+- test_sta_flag(sta, WLAN_STA_PS_DRIVER)) && -++ test_sta_flag(sta, WLAN_STA_PS_DRIVER) || -++ test_sta_flag(sta, WLAN_STA_PS_DELIVER)) && -+ !(info->flags & IEEE80211_TX_CTL_NO_PS_BUFFER))) { -+ int ac = skb_get_queue_mapping(tx->skb); - --- if (rdev->scan_req) { --+ if (rdev->scan_req || rdev->scan_msg) { -- err = -EBUSY; -- goto out; -- } --@@ -1481,7 +1491,7 @@ int cfg80211_wext_giwscan(struct net_dev -- if (IS_ERR(rdev)) -- return PTR_ERR(rdev); -- --- if (rdev->scan_req) --+ if (rdev->scan_req || rdev->scan_msg) -- return -EAGAIN; -- -- res = ieee80211_scan_results(rdev, info, extra, data->length); ----- a/net/wireless/sme.c --+++ b/net/wireless/sme.c --@@ -67,7 +67,7 @@ static int cfg80211_conn_scan(struct wir -- ASSERT_RDEV_LOCK(rdev); -- ASSERT_WDEV_LOCK(wdev); -- --- if (rdev->scan_req) --+ if (rdev->scan_req || rdev->scan_msg) -- return -EBUSY; -- -- if (wdev->conn->params.channel) ----- a/net/mac80211/mlme.c --+++ b/net/mac80211/mlme.c --@@ -1001,7 +1001,6 @@ ieee80211_sta_process_chanswitch(struct -- } -+@@ -486,7 +487,8 @@ ieee80211_tx_h_unicast_ps_buf(struct iee -+ * ahead and Tx the packet. -+ */ -+ if (!test_sta_flag(sta, WLAN_STA_PS_STA) && -+- !test_sta_flag(sta, WLAN_STA_PS_DRIVER)) { -++ !test_sta_flag(sta, WLAN_STA_PS_DRIVER) && -++ !test_sta_flag(sta, WLAN_STA_PS_DELIVER)) { -+ spin_unlock(&sta->ps_lock); -+ return TX_CONTINUE; -+ } -+@@ -1618,12 +1620,12 @@ netdev_tx_t ieee80211_monitor_start_xmit -+ { -+ struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); -+ struct ieee80211_chanctx_conf *chanctx_conf; -+- struct ieee80211_channel *chan; -+ struct ieee80211_radiotap_header *prthdr = -+ (struct ieee80211_radiotap_header *)skb->data; -+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); -+ struct ieee80211_hdr *hdr; -+ struct ieee80211_sub_if_data *tmp_sdata, *sdata; -++ struct cfg80211_chan_def *chandef; -+ u16 len_rthdr; -+ int hdrlen; - -- ifmgd->flags |= IEEE80211_STA_CSA_RECEIVED; --- sdata->vif.csa_active = true; -+@@ -1721,9 +1723,9 @@ netdev_tx_t ieee80211_monitor_start_xmit -+ } - -- mutex_lock(&local->chanctx_mtx); -- if (local->use_chanctx) { --@@ -1039,6 +1038,7 @@ ieee80211_sta_process_chanswitch(struct -- mutex_unlock(&local->chanctx_mtx); -+ if (chanctx_conf) -+- chan = chanctx_conf->def.chan; -++ chandef = &chanctx_conf->def; -+ else if (!local->use_chanctx) -+- chan = local->_oper_chandef.chan; -++ chandef = &local->_oper_chandef; -+ else -+ goto fail_rcu; - -- sdata->csa_chandef = csa_ie.chandef; --+ sdata->vif.csa_active = true; -+@@ -1743,10 +1745,11 @@ netdev_tx_t ieee80211_monitor_start_xmit -+ * radar detection by itself. We can do that later by adding a -+ * monitor flag interfaces used for AP support. -+ */ -+- if ((chan->flags & (IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_RADAR))) -++ if (!cfg80211_reg_can_beacon(local->hw.wiphy, chandef, -++ sdata->vif.type)) -+ goto fail_rcu; - -- if (csa_ie.mode) -- ieee80211_stop_queues_by_reason(&local->hw, ----- a/net/mac80211/chan.c --+++ b/net/mac80211/chan.c --@@ -196,6 +196,8 @@ static bool ieee80211_is_radar_required( -- { -- struct ieee80211_sub_if_data *sdata; -+- ieee80211_xmit(sdata, skb, chan->band); -++ ieee80211_xmit(sdata, skb, chandef->chan->band); -+ rcu_read_unlock(); - --+ lockdep_assert_held(&local->mtx); --+ -- rcu_read_lock(); -- list_for_each_entry_rcu(sdata, &local->interfaces, list) { -- if (sdata->radar_required) { ----- a/net/mac80211/ibss.c --+++ b/net/mac80211/ibss.c --@@ -294,7 +294,6 @@ static void __ieee80211_sta_join_ibss(st -- } -+ return NETDEV_TX_OK; -+@@ -2425,7 +2428,7 @@ static void ieee80211_set_csa(struct iee -+ u8 *beacon_data; -+ size_t beacon_data_len; -+ int i; -+- u8 count = sdata->csa_current_counter; -++ u8 count = beacon->csa_current_counter; - -- mutex_lock(&local->mtx); --- ieee80211_vif_release_channel(sdata); -- if (ieee80211_vif_use_channel(sdata, &chandef, -- ifibss->fixed_channel ? -- IEEE80211_CHANCTX_SHARED : --@@ -303,6 +302,7 @@ static void __ieee80211_sta_join_ibss(st -- mutex_unlock(&local->mtx); -+ switch (sdata->vif.type) { -+ case NL80211_IFTYPE_AP: -+@@ -2444,46 +2447,54 @@ static void ieee80211_set_csa(struct iee - return; - } --+ sdata->radar_required = radar_required; -- mutex_unlock(&local->mtx); -- -- memcpy(ifibss->bssid, bssid, ETH_ALEN); --@@ -318,7 +318,6 @@ static void __ieee80211_sta_join_ibss(st -- rcu_assign_pointer(ifibss->presp, presp); -- mgmt = (void *)presp->head; -- --- sdata->radar_required = radar_required; -- sdata->vif.bss_conf.enable_beacon = true; -- sdata->vif.bss_conf.beacon_int = beacon_int; -- sdata->vif.bss_conf.basic_rates = basic_rates; --@@ -386,7 +385,7 @@ static void __ieee80211_sta_join_ibss(st -- presp->head_len, 0, GFP_KERNEL); -- cfg80211_put_bss(local->hw.wiphy, bss); -- netif_carrier_on(sdata->dev); --- cfg80211_ibss_joined(sdata->dev, ifibss->bssid, GFP_KERNEL); --+ cfg80211_ibss_joined(sdata->dev, ifibss->bssid, chan, GFP_KERNEL); -- } -- -- static void ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, --@@ -802,6 +801,8 @@ ieee80211_ibss_process_chanswitch(struct -- int err; -- u32 sta_flags; - --+ sdata_assert_lock(sdata); --+ -- sta_flags = IEEE80211_STA_DISABLE_VHT; -- switch (ifibss->chandef.width) { -- case NL80211_CHAN_WIDTH_5: --@@ -1471,6 +1472,11 @@ static void ieee80211_rx_mgmt_probe_req( -- memcpy(((struct ieee80211_mgmt *) skb->data)->da, mgmt->sa, ETH_ALEN); -- ibss_dbg(sdata, "Sending ProbeResp to %pM\n", mgmt->sa); -- IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; -++ rcu_read_lock(); -+ for (i = 0; i < IEEE80211_MAX_CSA_COUNTERS_NUM; ++i) { -+- u16 counter_offset_beacon = -+- sdata->csa_counter_offset_beacon[i]; -+- u16 counter_offset_presp = sdata->csa_counter_offset_presp[i]; -+- -+- if (counter_offset_beacon) { -+- if (WARN_ON(counter_offset_beacon >= beacon_data_len)) -+- return; -+- -+- beacon_data[counter_offset_beacon] = count; -+- } -+- -+- if (sdata->vif.type == NL80211_IFTYPE_AP && -+- counter_offset_presp) { -+- rcu_read_lock(); -+- resp = rcu_dereference(sdata->u.ap.probe_resp); -++ resp = rcu_dereference(sdata->u.ap.probe_resp); -+ -+- /* If nl80211 accepted the offset, this should -+- * not happen. -+- */ -+- if (WARN_ON(!resp)) { -++ if (beacon->csa_counter_offsets[i]) { -++ if (WARN_ON_ONCE(beacon->csa_counter_offsets[i] >= -++ beacon_data_len)) { -+ rcu_read_unlock(); -+ return; -+ } -+- resp->data[counter_offset_presp] = count; -+- rcu_read_unlock(); - + --+ /* avoid excessive retries for probe request to wildcard SSIDs */ --+ if (pos[1] == 0) --+ IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_CTL_NO_ACK; -++ beacon_data[beacon->csa_counter_offsets[i]] = count; -+ } - + -- ieee80211_tx_skb(sdata, skb); -++ if (sdata->vif.type == NL80211_IFTYPE_AP && resp && -++ resp->csa_counter_offsets) -++ resp->data[resp->csa_counter_offsets[i]] = count; -+ } -++ rcu_read_unlock(); - } - ----- a/net/mac80211/mesh.c --+++ b/net/mac80211/mesh.c --@@ -872,6 +872,8 @@ ieee80211_mesh_process_chnswitch(struct -- if (!ifmsh->mesh_id) -- return false; -+ u8 ieee80211_csa_update_counter(struct ieee80211_vif *vif) -+ { -+ struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); -++ struct beacon_data *beacon = NULL; -++ u8 count = 0; -++ -++ rcu_read_lock(); -++ -++ if (sdata->vif.type == NL80211_IFTYPE_AP) -++ beacon = rcu_dereference(sdata->u.ap.beacon); -++ else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) -++ beacon = rcu_dereference(sdata->u.ibss.presp); -++ else if (ieee80211_vif_is_mesh(&sdata->vif)) -++ beacon = rcu_dereference(sdata->u.mesh.beacon); -++ -++ if (!beacon) -++ goto unlock; -+ -+- sdata->csa_current_counter--; -++ beacon->csa_current_counter--; -+ -+ /* the counter should never reach 0 */ -+- WARN_ON(!sdata->csa_current_counter); -++ WARN_ON_ONCE(!beacon->csa_current_counter); -++ count = beacon->csa_current_counter; -+ -+- return sdata->csa_current_counter; -++unlock: -++ rcu_read_unlock(); -++ return count; -+ } -+ EXPORT_SYMBOL(ieee80211_csa_update_counter); - --+ sdata_assert_lock(sdata); --+ -- sta_flags = IEEE80211_STA_DISABLE_VHT; -- switch (sdata->vif.bss_conf.chandef.width) { -- case NL80211_CHAN_WIDTH_20_NOHT: ----- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c --+++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c --@@ -4658,6 +4658,7 @@ brcmf_notify_connect_status(struct brcmf -- struct brcmf_cfg80211_info *cfg = ifp->drvr->config; -- struct net_device *ndev = ifp->ndev; -- struct brcmf_cfg80211_profile *profile = &ifp->vif->profile; --+ struct ieee80211_channel *chan; -- s32 err = 0; -- -- if (ifp->vif->mode == WL_MODE_AP) { --@@ -4665,9 +4666,10 @@ brcmf_notify_connect_status(struct brcmf -- } else if (brcmf_is_linkup(e)) { -- brcmf_dbg(CONN, "Linkup\n"); -- if (brcmf_is_ibssmode(ifp->vif)) { --+ chan = ieee80211_get_channel(cfg->wiphy, cfg->channel); -- memcpy(profile->bssid, e->addr, ETH_ALEN); -- wl_inform_ibss(cfg, ndev, e->addr); --- cfg80211_ibss_joined(ndev, e->addr, GFP_KERNEL); --+ cfg80211_ibss_joined(ndev, e->addr, chan, GFP_KERNEL); -- clear_bit(BRCMF_VIF_STATUS_CONNECTING, -- &ifp->vif->sme_state); -- set_bit(BRCMF_VIF_STATUS_CONNECTED, ----- a/drivers/net/wireless/libertas/cfg.c --+++ b/drivers/net/wireless/libertas/cfg.c --@@ -1766,7 +1766,8 @@ static void lbs_join_post(struct lbs_pri -- memcpy(priv->wdev->ssid, params->ssid, params->ssid_len); -- priv->wdev->ssid_len = params->ssid_len; -- --- cfg80211_ibss_joined(priv->dev, bssid, GFP_KERNEL); --+ cfg80211_ibss_joined(priv->dev, bssid, params->chandef.chan, --+ GFP_KERNEL); -- -- /* TODO: consider doing this at MACREG_INT_CODE_LINK_SENSED time */ -- priv->connect_status = LBS_CONNECTED; ----- a/drivers/net/wireless/mwifiex/cfg80211.c --+++ b/drivers/net/wireless/mwifiex/cfg80211.c --@@ -1881,7 +1881,8 @@ mwifiex_cfg80211_join_ibss(struct wiphy -- params->privacy); -- done: -- if (!ret) { --- cfg80211_ibss_joined(priv->netdev, priv->cfg_bssid, GFP_KERNEL); --+ cfg80211_ibss_joined(priv->netdev, priv->cfg_bssid, --+ params->chandef.chan, GFP_KERNEL); -- dev_dbg(priv->adapter->dev, -- "info: joined/created adhoc network with bssid" -- " %pM successfully\n", priv->cfg_bssid); ----- a/drivers/net/wireless/rndis_wlan.c --+++ b/drivers/net/wireless/rndis_wlan.c --@@ -2835,7 +2835,9 @@ static void rndis_wlan_do_link_up_work(s -- bssid, req_ie, req_ie_len, -- resp_ie, resp_ie_len, GFP_KERNEL); -- } else if (priv->infra_mode == NDIS_80211_INFRA_ADHOC) --- cfg80211_ibss_joined(usbdev->net, bssid, GFP_KERNEL); --+ cfg80211_ibss_joined(usbdev->net, bssid, --+ get_current_channel(usbdev, NULL), --+ GFP_KERNEL); -- -- kfree(info); -- ----- a/net/wireless/ibss.c --+++ b/net/wireless/ibss.c --@@ -14,7 +14,8 @@ -- #include "rdev-ops.h" -+@@ -2493,7 +2504,6 @@ bool ieee80211_csa_is_complete(struct ie -+ struct beacon_data *beacon = NULL; -+ u8 *beacon_data; -+ size_t beacon_data_len; -+- int counter_beacon = sdata->csa_counter_offset_beacon[0]; -+ int ret = false; - -+ if (!ieee80211_sdata_running(sdata)) -+@@ -2531,10 +2541,13 @@ bool ieee80211_csa_is_complete(struct ie -+ goto out; -+ } - ---void __cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid) --+void __cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid, --+ struct ieee80211_channel *channel) -- { -- struct wireless_dev *wdev = dev->ieee80211_ptr; -- struct cfg80211_bss *bss; --@@ -28,8 +29,7 @@ void __cfg80211_ibss_joined(struct net_d -- if (!wdev->ssid_len) -- return; -+- if (WARN_ON(counter_beacon > beacon_data_len)) -++ if (!beacon->csa_counter_offsets[0]) -++ goto out; -++ -++ if (WARN_ON_ONCE(beacon->csa_counter_offsets[0] > beacon_data_len)) -+ goto out; - --- bss = cfg80211_get_bss(wdev->wiphy, NULL, bssid, --- wdev->ssid, wdev->ssid_len, --+ bss = cfg80211_get_bss(wdev->wiphy, channel, bssid, NULL, 0, -- WLAN_CAPABILITY_IBSS, WLAN_CAPABILITY_IBSS); -+- if (beacon_data[counter_beacon] == 1) -++ if (beacon_data[beacon->csa_counter_offsets[0]] == 1) -+ ret = true; -+ out: -+ rcu_read_unlock(); -+@@ -2550,6 +2563,7 @@ __ieee80211_beacon_get(struct ieee80211_ -+ bool is_template) -+ { -+ struct ieee80211_local *local = hw_to_local(hw); -++ struct beacon_data *beacon = NULL; -+ struct sk_buff *skb = NULL; -+ struct ieee80211_tx_info *info; -+ struct ieee80211_sub_if_data *sdata = NULL; -+@@ -2571,10 +2585,10 @@ __ieee80211_beacon_get(struct ieee80211_ -+ -+ if (sdata->vif.type == NL80211_IFTYPE_AP) { -+ struct ieee80211_if_ap *ap = &sdata->u.ap; -+- struct beacon_data *beacon = rcu_dereference(ap->beacon); -+ -++ beacon = rcu_dereference(ap->beacon); -+ if (beacon) { -+- if (sdata->vif.csa_active) { -++ if (beacon->csa_counter_offsets[0]) { -+ if (!is_template) -+ ieee80211_csa_update_counter(vif); -+ -+@@ -2615,37 +2629,37 @@ __ieee80211_beacon_get(struct ieee80211_ -+ } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) { -+ struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; -+ struct ieee80211_hdr *hdr; -+- struct beacon_data *presp = rcu_dereference(ifibss->presp); -+ -+- if (!presp) -++ beacon = rcu_dereference(ifibss->presp); -++ if (!beacon) -+ goto out; - -- if (WARN_ON(!bss)) --@@ -54,21 +54,26 @@ void __cfg80211_ibss_joined(struct net_d -- #endif -- } -+- if (sdata->vif.csa_active) { -++ if (beacon->csa_counter_offsets[0]) { -+ if (!is_template) -+ ieee80211_csa_update_counter(vif); - ---void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid, gfp_t gfp) --+void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid, --+ struct ieee80211_channel *channel, gfp_t gfp) -- { -- struct wireless_dev *wdev = dev->ieee80211_ptr; -- struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); -- struct cfg80211_event *ev; -- unsigned long flags; -+- ieee80211_set_csa(sdata, presp); -++ ieee80211_set_csa(sdata, beacon); -+ } - --- trace_cfg80211_ibss_joined(dev, bssid); --+ trace_cfg80211_ibss_joined(dev, bssid, channel); --+ --+ if (WARN_ON(!channel)) --+ return; -+- skb = dev_alloc_skb(local->tx_headroom + presp->head_len + -++ skb = dev_alloc_skb(local->tx_headroom + beacon->head_len + -+ local->hw.extra_beacon_tailroom); -+ if (!skb) -+ goto out; -+ skb_reserve(skb, local->tx_headroom); -+- memcpy(skb_put(skb, presp->head_len), presp->head, -+- presp->head_len); -++ memcpy(skb_put(skb, beacon->head_len), beacon->head, -++ beacon->head_len); -+ -+ hdr = (struct ieee80211_hdr *) skb->data; -+ hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | -+ IEEE80211_STYPE_BEACON); -+ } else if (ieee80211_vif_is_mesh(&sdata->vif)) { -+ struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; -+- struct beacon_data *bcn = rcu_dereference(ifmsh->beacon); -+ -+- if (!bcn) -++ beacon = rcu_dereference(ifmsh->beacon); -++ if (!beacon) -+ goto out; - -- ev = kzalloc(sizeof(*ev), gfp); -- if (!ev) -- return; -+- if (sdata->vif.csa_active) { -++ if (beacon->csa_counter_offsets[0]) { -+ if (!is_template) -+ /* TODO: For mesh csa_counter is in TU, so -+ * decrementing it by one isn't correct, but -+@@ -2654,40 +2668,42 @@ __ieee80211_beacon_get(struct ieee80211_ -+ */ -+ ieee80211_csa_update_counter(vif); - -- ev->type = EVENT_IBSS_JOINED; --- memcpy(ev->cr.bssid, bssid, ETH_ALEN); --+ memcpy(ev->ij.bssid, bssid, ETH_ALEN); --+ ev->ij.channel = channel; -+- ieee80211_set_csa(sdata, bcn); -++ ieee80211_set_csa(sdata, beacon); -+ } - -- spin_lock_irqsave(&wdev->event_lock, flags); -- list_add_tail(&ev->list, &wdev->event_list); --@@ -117,6 +122,7 @@ int __cfg80211_join_ibss(struct cfg80211 -+ if (ifmsh->sync_ops) -+- ifmsh->sync_ops->adjust_tbtt(sdata, bcn); -++ ifmsh->sync_ops->adjust_tbtt(sdata, beacon); -+ -+ skb = dev_alloc_skb(local->tx_headroom + -+- bcn->head_len + -++ beacon->head_len + -+ 256 + /* TIM IE */ -+- bcn->tail_len + -++ beacon->tail_len + -+ local->hw.extra_beacon_tailroom); -+ if (!skb) -+ goto out; -+ skb_reserve(skb, local->tx_headroom); -+- memcpy(skb_put(skb, bcn->head_len), bcn->head, bcn->head_len); -++ memcpy(skb_put(skb, beacon->head_len), beacon->head, -++ beacon->head_len); -+ ieee80211_beacon_add_tim(sdata, &ifmsh->ps, skb, is_template); -+ -+ if (offs) { -+- offs->tim_offset = bcn->head_len; -+- offs->tim_length = skb->len - bcn->head_len; -++ offs->tim_offset = beacon->head_len; -++ offs->tim_length = skb->len - beacon->head_len; -+ } - -- wdev->ibss_fixed = params->channel_fixed; -- wdev->ibss_dfs_possible = params->userspace_handles_dfs; --+ wdev->chandef = params->chandef; -- #ifdef CPTCFG_CFG80211_WEXT -- wdev->wext.ibss.chandef = params->chandef; -- #endif --@@ -200,6 +206,7 @@ static void __cfg80211_clear_ibss(struct -- -- wdev->current_bss = NULL; -- wdev->ssid_len = 0; --+ memset(&wdev->chandef, 0, sizeof(wdev->chandef)); -- #ifdef CPTCFG_CFG80211_WEXT -- if (!nowext) -- wdev->wext.ibss.ssid_len = 0; ----- a/net/wireless/trace.h --+++ b/net/wireless/trace.h --@@ -2278,11 +2278,6 @@ DECLARE_EVENT_CLASS(cfg80211_rx_evt, -- TP_printk(NETDEV_PR_FMT ", " MAC_PR_FMT, NETDEV_PR_ARG, MAC_PR_ARG(addr)) -- ); -+- memcpy(skb_put(skb, bcn->tail_len), bcn->tail, bcn->tail_len); -++ memcpy(skb_put(skb, beacon->tail_len), beacon->tail, -++ beacon->tail_len); -+ } else { -+ WARN_ON(1); -+ goto out; -+ } - ---DEFINE_EVENT(cfg80211_rx_evt, cfg80211_ibss_joined, --- TP_PROTO(struct net_device *netdev, const u8 *addr), --- TP_ARGS(netdev, addr) ---); --- -- DEFINE_EVENT(cfg80211_rx_evt, cfg80211_rx_spurious_frame, -- TP_PROTO(struct net_device *netdev, const u8 *addr), -- TP_ARGS(netdev, addr) --@@ -2293,6 +2288,24 @@ DEFINE_EVENT(cfg80211_rx_evt, cfg80211_r -- TP_ARGS(netdev, addr) -- ); -+ /* CSA offsets */ -+- if (offs) { -++ if (offs && beacon) { -+ int i; -+ -+ for (i = 0; i < IEEE80211_MAX_CSA_COUNTERS_NUM; i++) { -+- u16 csa_off = sdata->csa_counter_offset_beacon[i]; -++ u16 csa_off = beacon->csa_counter_offsets[i]; -+ -+ if (!csa_off) -+ continue; -+--- a/drivers/net/wireless/rt2x00/rt2800lib.c -++++ b/drivers/net/wireless/rt2x00/rt2800lib.c -+@@ -947,6 +947,40 @@ static inline u8 rt2800_get_beacon_offse -+ return BEACON_BASE_TO_OFFSET(rt2800_hw_beacon_base(rt2x00dev, index)); -+ } - --+TRACE_EVENT(cfg80211_ibss_joined, --+ TP_PROTO(struct net_device *netdev, const u8 *bssid, --+ struct ieee80211_channel *channel), --+ TP_ARGS(netdev, bssid, channel), --+ TP_STRUCT__entry( --+ NETDEV_ENTRY --+ MAC_ENTRY(bssid) --+ CHAN_ENTRY --+ ), --+ TP_fast_assign( --+ NETDEV_ASSIGN; --+ MAC_ASSIGN(bssid, bssid); --+ CHAN_ASSIGN(channel); --+ ), --+ TP_printk(NETDEV_PR_FMT ", bssid: " MAC_PR_FMT ", " CHAN_PR_FMT, --+ NETDEV_PR_ARG, MAC_PR_ARG(bssid), CHAN_PR_ARG) --+); -++static void rt2800_update_beacons_setup(struct rt2x00_dev *rt2x00dev) -++{ -++ struct data_queue *queue = rt2x00dev->bcn; -++ struct queue_entry *entry; -++ int i, bcn_num = 0; -++ u64 off, reg = 0; -++ u32 bssid_dw1; - + -- TRACE_EVENT(cfg80211_probe_status, -- TP_PROTO(struct net_device *netdev, const u8 *addr, u64 cookie, -- bool acked), ----- a/net/wireless/util.c --+++ b/net/wireless/util.c --@@ -820,7 +820,8 @@ void cfg80211_process_wdev_events(struct -- ev->dc.reason, true); -- break; -- case EVENT_IBSS_JOINED: --- __cfg80211_ibss_joined(wdev->netdev, ev->ij.bssid); --+ __cfg80211_ibss_joined(wdev->netdev, ev->ij.bssid, --+ ev->ij.channel); -- break; -- } -- wdev_unlock(wdev); --@@ -1356,7 +1357,7 @@ int cfg80211_can_use_iftype_chan(struct -- */ -- mutex_lock_nested(&wdev_iter->mtx, 1); -- __acquire(wdev_iter->mtx); --- cfg80211_get_chan_state(wdev_iter, &ch, &chmode); --+ cfg80211_get_chan_state(wdev_iter, &ch, &chmode, &radar_detect); -- wdev_unlock(wdev_iter); -- -- switch (chmode) { ----- a/net/wireless/chan.c --+++ b/net/wireless/chan.c --@@ -642,7 +642,8 @@ int cfg80211_set_monitor_channel(struct -- void -- cfg80211_get_chan_state(struct wireless_dev *wdev, -- struct ieee80211_channel **chan, --- enum cfg80211_chan_mode *chanmode) --+ enum cfg80211_chan_mode *chanmode, --+ u8 *radar_detect) -- { -- *chan = NULL; -- *chanmode = CHAN_MODE_UNDEFINED; --@@ -660,6 +661,11 @@ cfg80211_get_chan_state(struct wireless_ -- !wdev->ibss_dfs_possible) -- ? CHAN_MODE_SHARED -- : CHAN_MODE_EXCLUSIVE; -++ /* -++ * Setup offsets of all active beacons in BCN_OFFSET{0,1} registers. -++ */ -++ for (i = 0; i < queue->limit; i++) { -++ entry = &queue->entries[i]; -++ if (!test_bit(ENTRY_BCN_ENABLED, &entry->flags)) -++ continue; -++ off = rt2800_get_beacon_offset(rt2x00dev, entry->entry_idx); -++ reg |= off << (8 * bcn_num); -++ bcn_num++; -++ } - + --+ /* consider worst-case - IBSS can try to return to the --+ * original user-specified channel as creator */ --+ if (wdev->ibss_dfs_possible) --+ *radar_detect |= BIT(wdev->chandef.width); -- return; -- } -- break; --@@ -674,17 +680,26 @@ cfg80211_get_chan_state(struct wireless_ -- case NL80211_IFTYPE_AP: -- case NL80211_IFTYPE_P2P_GO: -- if (wdev->cac_started) { --- *chan = wdev->channel; --+ *chan = wdev->chandef.chan; -- *chanmode = CHAN_MODE_SHARED; --+ *radar_detect |= BIT(wdev->chandef.width); -- } else if (wdev->beacon_interval) { --- *chan = wdev->channel; --+ *chan = wdev->chandef.chan; -- *chanmode = CHAN_MODE_SHARED; -++ WARN_ON_ONCE(bcn_num != rt2x00dev->intf_beaconing); - + --+ if (cfg80211_chandef_dfs_required(wdev->wiphy, --+ &wdev->chandef)) --+ *radar_detect |= BIT(wdev->chandef.width); -- } -- return; -- case NL80211_IFTYPE_MESH_POINT: -- if (wdev->mesh_id_len) { --- *chan = wdev->channel; --+ *chan = wdev->chandef.chan; -- *chanmode = CHAN_MODE_SHARED; -++ rt2800_register_write(rt2x00dev, BCN_OFFSET0, (u32) reg); -++ rt2800_register_write(rt2x00dev, BCN_OFFSET1, (u32) (reg >> 32)); -++ -++ /* -++ * H/W sends up to MAC_BSSID_DW1_BSS_BCN_NUM + 1 consecutive beacons. -++ */ -++ rt2800_register_read(rt2x00dev, MAC_BSSID_DW1, &bssid_dw1); -++ rt2x00_set_field32(&bssid_dw1, MAC_BSSID_DW1_BSS_BCN_NUM, -++ bcn_num > 0 ? bcn_num - 1 : 0); -++ rt2800_register_write(rt2x00dev, MAC_BSSID_DW1, bssid_dw1); -++} -++ -+ void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc) -+ { -+ struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; -+@@ -1003,6 +1037,12 @@ void rt2800_write_beacon(struct queue_en -+ -+ rt2800_register_multiwrite(rt2x00dev, beacon_base, entry->skb->data, -+ entry->skb->len + padding_len); -++ __set_bit(ENTRY_BCN_ENABLED, &entry->flags); - + --+ if (cfg80211_chandef_dfs_required(wdev->wiphy, --+ &wdev->chandef)) --+ *radar_detect |= BIT(wdev->chandef.width); -- } -- return; -- case NL80211_IFTYPE_MONITOR: ----- a/net/wireless/mesh.c --+++ b/net/wireless/mesh.c --@@ -195,7 +195,7 @@ int __cfg80211_join_mesh(struct cfg80211 -- if (!err) { -- memcpy(wdev->ssid, setup->mesh_id, setup->mesh_id_len); -- wdev->mesh_id_len = setup->mesh_id_len; --- wdev->channel = setup->chandef.chan; --+ wdev->chandef = setup->chandef; -- } -++ /* -++ * Change global beacons settings. -++ */ -++ rt2800_update_beacons_setup(rt2x00dev); - -- return err; --@@ -244,7 +244,7 @@ int cfg80211_set_mesh_channel(struct cfg -- err = rdev_libertas_set_mesh_channel(rdev, wdev->netdev, -- chandef->chan); -- if (!err) --- wdev->channel = chandef->chan; --+ wdev->chandef = *chandef; -+ /* -+ * Restore beaconing state. -+@@ -1053,8 +1093,13 @@ void rt2800_clear_beacon(struct queue_en -+ * Clear beacon. -+ */ -+ rt2800_clear_beacon_register(rt2x00dev, entry->entry_idx); -++ __clear_bit(ENTRY_BCN_ENABLED, &entry->flags); - -- return err; -- } --@@ -276,7 +276,7 @@ static int __cfg80211_leave_mesh(struct -- err = rdev_leave_mesh(rdev, dev); -- if (!err) { -- wdev->mesh_id_len = 0; --- wdev->channel = NULL; --+ memset(&wdev->chandef, 0, sizeof(wdev->chandef)); -- rdev_set_qos_map(rdev, dev, NULL); -- } -+ /* -++ * Change global beacons settings. -++ */ -++ rt2800_update_beacons_setup(rt2x00dev); -++ /* -+ * Restore beaconing state. -+ */ -+ rt2800_register_write(rt2x00dev, BCN_TIME_CFG, orig_reg); -+@@ -1556,7 +1601,7 @@ void rt2800_config_intf(struct rt2x00_de -+ if (!is_zero_ether_addr((const u8 *)conf->bssid)) { -+ reg = le32_to_cpu(conf->bssid[1]); -+ rt2x00_set_field32(®, MAC_BSSID_DW1_BSS_ID_MASK, 3); -+- rt2x00_set_field32(®, MAC_BSSID_DW1_BSS_BCN_NUM, 7); -++ rt2x00_set_field32(®, MAC_BSSID_DW1_BSS_BCN_NUM, 0); -+ conf->bssid[1] = cpu_to_le32(reg); -+ } - ----- a/net/wireless/mlme.c --+++ b/net/wireless/mlme.c --@@ -772,7 +772,7 @@ void cfg80211_cac_event(struct net_devic -- if (WARN_ON(!wdev->cac_started)) -- return; -+@@ -4517,28 +4562,6 @@ static int rt2800_init_registers(struct -+ if (ret) -+ return ret; -+ -+- rt2800_register_read(rt2x00dev, BCN_OFFSET0, ®); -+- rt2x00_set_field32(®, BCN_OFFSET0_BCN0, -+- rt2800_get_beacon_offset(rt2x00dev, 0)); -+- rt2x00_set_field32(®, BCN_OFFSET0_BCN1, -+- rt2800_get_beacon_offset(rt2x00dev, 1)); -+- rt2x00_set_field32(®, BCN_OFFSET0_BCN2, -+- rt2800_get_beacon_offset(rt2x00dev, 2)); -+- rt2x00_set_field32(®, BCN_OFFSET0_BCN3, -+- rt2800_get_beacon_offset(rt2x00dev, 3)); -+- rt2800_register_write(rt2x00dev, BCN_OFFSET0, reg); -+- -+- rt2800_register_read(rt2x00dev, BCN_OFFSET1, ®); -+- rt2x00_set_field32(®, BCN_OFFSET1_BCN4, -+- rt2800_get_beacon_offset(rt2x00dev, 4)); -+- rt2x00_set_field32(®, BCN_OFFSET1_BCN5, -+- rt2800_get_beacon_offset(rt2x00dev, 5)); -+- rt2x00_set_field32(®, BCN_OFFSET1_BCN6, -+- rt2800_get_beacon_offset(rt2x00dev, 6)); -+- rt2x00_set_field32(®, BCN_OFFSET1_BCN7, -+- rt2800_get_beacon_offset(rt2x00dev, 7)); -+- rt2800_register_write(rt2x00dev, BCN_OFFSET1, reg); -+- -+ rt2800_register_write(rt2x00dev, LEGACY_BASIC_RATE, 0x0000013f); -+ rt2800_register_write(rt2x00dev, HT_BASIC_RATE, 0x00008003); - --- if (WARN_ON(!wdev->channel)) --+ if (WARN_ON(!wdev->chandef.chan)) -+--- a/drivers/net/wireless/rt2x00/rt2x00dev.c -++++ b/drivers/net/wireless/rt2x00/rt2x00dev.c -+@@ -141,8 +141,11 @@ static void rt2x00lib_intf_scheduled_ite -+ if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) - return; - -- switch (event) { ----- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c --+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c --@@ -5065,6 +5065,10 @@ static u16 ar9003_hw_get_max_edge_power( -- break; -- } -- } --+ --+ if (is2GHz && !twiceMaxEdgePower) --+ twiceMaxEdgePower = 60; --+ -- return twiceMaxEdgePower; -+- if (test_and_clear_bit(DELAYED_UPDATE_BEACON, &intf->delayed_flags)) -++ if (test_and_clear_bit(DELAYED_UPDATE_BEACON, &intf->delayed_flags)) { -++ mutex_lock(&intf->beacon_skb_mutex); -+ rt2x00queue_update_beacon(rt2x00dev, vif); -++ mutex_unlock(&intf->beacon_skb_mutex); -++ } - } - ----- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c --+++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c --@@ -23,10 +23,11 @@ -- #define MAX_MEASUREMENT MAX_IQCAL_MEASUREMENT -- #define MAX_MAG_DELTA 11 -- #define MAX_PHS_DELTA 10 --+#define MAXIQCAL 3 -- -- struct coeff { --- int mag_coeff[AR9300_MAX_CHAINS][MAX_MEASUREMENT]; --- int phs_coeff[AR9300_MAX_CHAINS][MAX_MEASUREMENT]; --+ int mag_coeff[AR9300_MAX_CHAINS][MAX_MEASUREMENT][MAXIQCAL]; --+ int phs_coeff[AR9300_MAX_CHAINS][MAX_MEASUREMENT][MAXIQCAL]; -- int iqc_coeff[2]; -- }; -+ static void rt2x00lib_intf_scheduled(struct work_struct *work) -+@@ -216,7 +219,7 @@ static void rt2x00lib_beaconupdate_iter( -+ * never be called for USB devices. -+ */ -+ WARN_ON(rt2x00_is_usb(rt2x00dev)); -+- rt2x00queue_update_beacon_locked(rt2x00dev, vif); -++ rt2x00queue_update_beacon(rt2x00dev, vif); -+ } - --@@ -800,7 +801,7 @@ static bool ar9003_hw_calc_iq_corr(struc -- if (q_q_coff > 63) -- q_q_coff = 63; -+ void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev) -+--- a/drivers/net/wireless/rt2x00/rt2x00mac.c -++++ b/drivers/net/wireless/rt2x00/rt2x00mac.c -+@@ -624,25 +624,24 @@ void rt2x00mac_bss_info_changed(struct i -+ * Start/stop beaconing. -+ */ -+ if (changes & BSS_CHANGED_BEACON_ENABLED) { -++ mutex_lock(&intf->beacon_skb_mutex); -+ if (!bss_conf->enable_beacon && intf->enable_beacon) { -+ rt2x00dev->intf_beaconing--; -+ intf->enable_beacon = false; -+- /* -+- * Clear beacon in the H/W for this vif. This is needed -+- * to disable beaconing on this particular interface -+- * and keep it running on other interfaces. -+- */ -+- rt2x00queue_clear_beacon(rt2x00dev, vif); - --- iqc_coeff[0] = (q_q_coff * 128) + q_i_coff; --+ iqc_coeff[0] = (q_q_coff * 128) + (0x7f & q_i_coff); -+ if (rt2x00dev->intf_beaconing == 0) { -+ /* -+ * Last beaconing interface disabled -+ * -> stop beacon queue. -+ */ -+- mutex_lock(&intf->beacon_skb_mutex); -+ rt2x00queue_stop_queue(rt2x00dev->bcn); -+- mutex_unlock(&intf->beacon_skb_mutex); -+ } -++ /* -++ * Clear beacon in the H/W for this vif. This is needed -++ * to disable beaconing on this particular interface -++ * and keep it running on other interfaces. -++ */ -++ rt2x00queue_clear_beacon(rt2x00dev, vif); -+ } else if (bss_conf->enable_beacon && !intf->enable_beacon) { -+ rt2x00dev->intf_beaconing++; -+ intf->enable_beacon = true; -+@@ -658,11 +657,10 @@ void rt2x00mac_bss_info_changed(struct i -+ * First beaconing interface enabled -+ * -> start beacon queue. -+ */ -+- mutex_lock(&intf->beacon_skb_mutex); -+ rt2x00queue_start_queue(rt2x00dev->bcn); -+- mutex_unlock(&intf->beacon_skb_mutex); -+ } -+ } -++ mutex_unlock(&intf->beacon_skb_mutex); -+ } - -- ath_dbg(common, CALIBRATE, "tx chain %d: iq corr coeff=%x\n", -- chain_idx, iqc_coeff[0]); --@@ -831,7 +832,7 @@ static bool ar9003_hw_calc_iq_corr(struc -- if (q_q_coff > 63) -- q_q_coff = 63; -+ /* -+--- a/drivers/net/wireless/rt2x00/rt2x00queue.c -++++ b/drivers/net/wireless/rt2x00/rt2x00queue.c -+@@ -754,8 +754,6 @@ int rt2x00queue_clear_beacon(struct rt2x -+ if (unlikely(!intf->beacon)) -+ return -ENOBUFS; - --- iqc_coeff[1] = (q_q_coff * 128) + q_i_coff; --+ iqc_coeff[1] = (q_q_coff * 128) + (0x7f & q_i_coff); -+- mutex_lock(&intf->beacon_skb_mutex); -+- -+ /* -+ * Clean up the beacon skb. -+ */ -+@@ -768,13 +766,11 @@ int rt2x00queue_clear_beacon(struct rt2x -+ if (rt2x00dev->ops->lib->clear_beacon) -+ rt2x00dev->ops->lib->clear_beacon(intf->beacon); - -- ath_dbg(common, CALIBRATE, "rx chain %d: iq corr coeff=%x\n", -- chain_idx, iqc_coeff[1]); --@@ -839,7 +840,8 @@ static bool ar9003_hw_calc_iq_corr(struc -- return true; -+- mutex_unlock(&intf->beacon_skb_mutex); -+- -+ return 0; - } - ---static void ar9003_hw_detect_outlier(int *mp_coeff, int nmeasurement, --+static void ar9003_hw_detect_outlier(int mp_coeff[][MAXIQCAL], --+ int nmeasurement, -- int max_delta) -+-int rt2x00queue_update_beacon_locked(struct rt2x00_dev *rt2x00dev, -+- struct ieee80211_vif *vif) -++int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev, -++ struct ieee80211_vif *vif) - { -- int mp_max = -64, max_idx = 0; --@@ -848,20 +850,20 @@ static void ar9003_hw_detect_outlier(int -- -- /* find min/max mismatch across all calibrated gains */ -- for (i = 0; i < nmeasurement; i++) { --- if (mp_coeff[i] > mp_max) { --- mp_max = mp_coeff[i]; --+ if (mp_coeff[i][0] > mp_max) { --+ mp_max = mp_coeff[i][0]; -- max_idx = i; --- } else if (mp_coeff[i] < mp_min) { --- mp_min = mp_coeff[i]; --+ } else if (mp_coeff[i][0] < mp_min) { --+ mp_min = mp_coeff[i][0]; -- min_idx = i; -- } -- } -+ struct rt2x00_intf *intf = vif_to_intf(vif); -+ struct skb_frame_desc *skbdesc; -+@@ -815,19 +811,6 @@ int rt2x00queue_update_beacon_locked(str - -- /* find average (exclude max abs value) */ -- for (i = 0; i < nmeasurement; i++) { --- if ((abs(mp_coeff[i]) < abs(mp_max)) || --- (abs(mp_coeff[i]) < abs(mp_min))) { --- mp_avg += mp_coeff[i]; --+ if ((abs(mp_coeff[i][0]) < abs(mp_max)) || --+ (abs(mp_coeff[i][0]) < abs(mp_min))) { --+ mp_avg += mp_coeff[i][0]; -- mp_count++; -- } -- } --@@ -873,7 +875,7 @@ static void ar9003_hw_detect_outlier(int -- if (mp_count) -- mp_avg /= mp_count; -- else --- mp_avg = mp_coeff[nmeasurement - 1]; --+ mp_avg = mp_coeff[nmeasurement - 1][0]; -- -- /* detect outlier */ -- if (abs(mp_max - mp_min) > max_delta) { --@@ -882,15 +884,16 @@ static void ar9003_hw_detect_outlier(int -- else -- outlier_idx = min_idx; -- --- mp_coeff[outlier_idx] = mp_avg; --+ mp_coeff[outlier_idx][0] = mp_avg; -- } - } - ---static void ar9003_hw_tx_iqcal_load_avg_2_passes(struct ath_hw *ah, --- struct coeff *coeff, --- bool is_reusable) --+static void ar9003_hw_tx_iq_cal_outlier_detection(struct ath_hw *ah, --+ struct coeff *coeff, --+ bool is_reusable) -- { -- int i, im, nmeasurement; --+ int magnitude, phase; -- u32 tx_corr_coeff[MAX_MEASUREMENT][AR9300_MAX_CHAINS]; -- struct ath9k_hw_cal_data *caldata = ah->caldata; -- --@@ -920,21 +923,30 @@ static void ar9003_hw_tx_iqcal_load_avg_ -- if (nmeasurement > MAX_MEASUREMENT) -- nmeasurement = MAX_MEASUREMENT; -- --- /* detect outlier only if nmeasurement > 1 */ --- if (nmeasurement > 1) { --- /* Detect magnitude outlier */ --- ar9003_hw_detect_outlier(coeff->mag_coeff[i], --- nmeasurement, MAX_MAG_DELTA); -+-int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev, -+- struct ieee80211_vif *vif) -+-{ -+- struct rt2x00_intf *intf = vif_to_intf(vif); -+- int ret; - - --- /* Detect phase outlier */ --- ar9003_hw_detect_outlier(coeff->phs_coeff[i], --- nmeasurement, MAX_PHS_DELTA); --+ /* --+ * Skip normal outlier detection for AR9550. --+ */ --+ if (!AR_SREV_9550(ah)) { --+ /* detect outlier only if nmeasurement > 1 */ --+ if (nmeasurement > 1) { --+ /* Detect magnitude outlier */ --+ ar9003_hw_detect_outlier(coeff->mag_coeff[i], --+ nmeasurement, --+ MAX_MAG_DELTA); --+ --+ /* Detect phase outlier */ --+ ar9003_hw_detect_outlier(coeff->phs_coeff[i], --+ nmeasurement, --+ MAX_PHS_DELTA); --+ } -- } -- -- for (im = 0; im < nmeasurement; im++) { --+ magnitude = coeff->mag_coeff[i][im][0]; --+ phase = coeff->phs_coeff[i][im][0]; -+- mutex_lock(&intf->beacon_skb_mutex); -+- ret = rt2x00queue_update_beacon_locked(rt2x00dev, vif); -+- mutex_unlock(&intf->beacon_skb_mutex); -+- -+- return ret; -+-} -+- -+ bool rt2x00queue_for_each_entry(struct data_queue *queue, -+ enum queue_index start, -+ enum queue_index end, -+--- a/drivers/net/wireless/rt2x00/rt2x00queue.h -++++ b/drivers/net/wireless/rt2x00/rt2x00queue.h -+@@ -353,6 +353,7 @@ struct txentry_desc { -+ */ -+ enum queue_entry_flags { -+ ENTRY_BCN_ASSIGNED, -++ ENTRY_BCN_ENABLED, -+ ENTRY_OWNER_DEVICE_DATA, -+ ENTRY_DATA_PENDING, -+ ENTRY_DATA_IO_FAILED, -+--- a/drivers/net/wireless/ath/ath9k/main.c -++++ b/drivers/net/wireless/ath/ath9k/main.c -+@@ -1757,7 +1757,6 @@ out: -+ void ath9k_update_p2p_ps(struct ath_softc *sc, struct ieee80211_vif *vif) -+ { -+ struct ath_vif *avp = (void *)vif->drv_priv; -+- unsigned long flags; -+ u32 tsf; - --- coeff->iqc_coeff[0] = (coeff->mag_coeff[i][im] & 0x7f) | --- ((coeff->phs_coeff[i][im] & 0x7f) << 7); --+ coeff->iqc_coeff[0] = --+ (phase & 0x7f) | ((magnitude & 0x7f) << 7); -+ if (!sc->p2p_ps_timer) -+@@ -1767,14 +1766,9 @@ void ath9k_update_p2p_ps(struct ath_soft -+ return; - -- if ((im % 2) == 0) -- REG_RMW_FIELD(ah, tx_corr_coeff[im][i], --@@ -991,7 +1003,63 @@ static bool ar9003_hw_tx_iq_cal_run(stru -- return true; -+ sc->p2p_ps_vif = avp; -+- -+- spin_lock_irqsave(&sc->sc_pm_lock, flags); -+- if (!(sc->ps_flags & PS_BEACON_SYNC)) { -+- tsf = ath9k_hw_gettsf32(sc->sc_ah); -+- ieee80211_parse_p2p_noa(&vif->bss_conf.p2p_noa_attr, &avp->noa, tsf); -+- ath9k_update_p2p_ps_timer(sc, avp); -+- } -+- spin_unlock_irqrestore(&sc->sc_pm_lock, flags); -++ tsf = ath9k_hw_gettsf32(sc->sc_ah); -++ ieee80211_parse_p2p_noa(&vif->bss_conf.p2p_noa_attr, &avp->noa, tsf); -++ ath9k_update_p2p_ps_timer(sc, avp); - } - ---static void ar9003_hw_tx_iq_cal_post_proc(struct ath_hw *ah, bool is_reusable) --+static void __ar955x_tx_iq_cal_sort(struct ath_hw *ah, --+ struct coeff *coeff, --+ int i, int nmeasurement) --+{ --+ struct ath_common *common = ath9k_hw_common(ah); --+ int im, ix, iy, temp; --+ --+ for (im = 0; im < nmeasurement; im++) { --+ for (ix = 0; ix < MAXIQCAL - 1; ix++) { --+ for (iy = ix + 1; iy <= MAXIQCAL - 1; iy++) { --+ if (coeff->mag_coeff[i][im][iy] < --+ coeff->mag_coeff[i][im][ix]) { --+ temp = coeff->mag_coeff[i][im][ix]; --+ coeff->mag_coeff[i][im][ix] = --+ coeff->mag_coeff[i][im][iy]; --+ coeff->mag_coeff[i][im][iy] = temp; --+ } --+ if (coeff->phs_coeff[i][im][iy] < --+ coeff->phs_coeff[i][im][ix]) { --+ temp = coeff->phs_coeff[i][im][ix]; --+ coeff->phs_coeff[i][im][ix] = --+ coeff->phs_coeff[i][im][iy]; --+ coeff->phs_coeff[i][im][iy] = temp; --+ } --+ } --+ } --+ coeff->mag_coeff[i][im][0] = coeff->mag_coeff[i][im][MAXIQCAL / 2]; --+ coeff->phs_coeff[i][im][0] = coeff->phs_coeff[i][im][MAXIQCAL / 2]; --+ --+ ath_dbg(common, CALIBRATE, --+ "IQCAL: Median [ch%d][gain%d]: mag = %d phase = %d\n", --+ i, im, --+ coeff->mag_coeff[i][im][0], --+ coeff->phs_coeff[i][im][0]); --+ } --+} --+ --+static bool ar955x_tx_iq_cal_median(struct ath_hw *ah, --+ struct coeff *coeff, --+ int iqcal_idx, --+ int nmeasurement) --+{ --+ int i; --+ --+ if ((iqcal_idx + 1) != MAXIQCAL) --+ return false; --+ --+ for (i = 0; i < AR9300_MAX_CHAINS; i++) { --+ __ar955x_tx_iq_cal_sort(ah, coeff, i, nmeasurement); --+ } --+ --+ return true; --+} --+ --+static void ar9003_hw_tx_iq_cal_post_proc(struct ath_hw *ah, --+ int iqcal_idx, --+ bool is_reusable) -- { -+ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, -+@@ -1791,6 +1785,7 @@ static void ath9k_bss_info_changed(struc -+ struct ath_hw *ah = sc->sc_ah; - struct ath_common *common = ath9k_hw_common(ah); -- const u32 txiqcal_status[AR9300_MAX_CHAINS] = { --@@ -1004,10 +1072,11 @@ static void ar9003_hw_tx_iq_cal_post_pro -- AR_PHY_CHAN_INFO_TAB_1, -- AR_PHY_CHAN_INFO_TAB_2, -- }; --- struct coeff coeff; --+ static struct coeff coeff; -- s32 iq_res[6]; -- int i, im, j; --- int nmeasurement; --+ int nmeasurement = 0; --+ bool outlier_detect = true; -- -- for (i = 0; i < AR9300_MAX_CHAINS; i++) { -- if (!(ah->txchainmask & (1 << i))) --@@ -1065,17 +1134,23 @@ static void ar9003_hw_tx_iq_cal_post_pro -- goto tx_iqcal_fail; -- } -- --- coeff.mag_coeff[i][im] = coeff.iqc_coeff[0] & 0x7f; --- coeff.phs_coeff[i][im] = --+ coeff.phs_coeff[i][im][iqcal_idx] = --+ coeff.iqc_coeff[0] & 0x7f; --+ coeff.mag_coeff[i][im][iqcal_idx] = -- (coeff.iqc_coeff[0] >> 7) & 0x7f; -- --- if (coeff.mag_coeff[i][im] > 63) --- coeff.mag_coeff[i][im] -= 128; --- if (coeff.phs_coeff[i][im] > 63) --- coeff.phs_coeff[i][im] -= 128; --+ if (coeff.mag_coeff[i][im][iqcal_idx] > 63) --+ coeff.mag_coeff[i][im][iqcal_idx] -= 128; --+ if (coeff.phs_coeff[i][im][iqcal_idx] > 63) --+ coeff.phs_coeff[i][im][iqcal_idx] -= 128; -- } -+ struct ath_vif *avp = (void *)vif->drv_priv; -++ unsigned long flags; -+ int slottime; -+ -+ ath9k_ps_wakeup(sc); -+@@ -1853,7 +1848,10 @@ static void ath9k_bss_info_changed(struc -+ -+ if (changed & BSS_CHANGED_P2P_PS) { -+ spin_lock_bh(&sc->sc_pcu_lock); -+- ath9k_update_p2p_ps(sc, vif); -++ spin_lock_irqsave(&sc->sc_pm_lock, flags); -++ if (!(sc->ps_flags & PS_BEACON_SYNC)) -++ ath9k_update_p2p_ps(sc, vif); -++ spin_unlock_irqrestore(&sc->sc_pm_lock, flags); -+ spin_unlock_bh(&sc->sc_pcu_lock); - } --- ar9003_hw_tx_iqcal_load_avg_2_passes(ah, &coeff, is_reusable); --+ --+ if (AR_SREV_9550(ah)) --+ outlier_detect = ar955x_tx_iq_cal_median(ah, &coeff, --+ iqcal_idx, nmeasurement); --+ if (outlier_detect) --+ ar9003_hw_tx_iq_cal_outlier_detection(ah, &coeff, is_reusable); -- -- return; - --@@ -1409,7 +1484,7 @@ skip_tx_iqcal: -- } -+@@ -2232,14 +2230,6 @@ static void ath9k_sw_scan_complete(struc -+ clear_bit(ATH_OP_SCANNING, &common->op_flags); -+ } - -- if (txiqcal_done) --- ar9003_hw_tx_iq_cal_post_proc(ah, is_reusable); --+ ar9003_hw_tx_iq_cal_post_proc(ah, 0, is_reusable); -- else if (caldata && test_bit(TXIQCAL_DONE, &caldata->cal_flags)) -- ar9003_hw_tx_iq_cal_reload(ah); -+-static void ath9k_channel_switch_beacon(struct ieee80211_hw *hw, -+- struct ieee80211_vif *vif, -+- struct cfg80211_chan_def *chandef) -+-{ -+- /* depend on vif->csa_active only */ -+- return; -+-} -+- -+ struct ieee80211_ops ath9k_ops = { -+ .tx = ath9k_tx, -+ .start = ath9k_start, -+@@ -2287,5 +2277,4 @@ struct ieee80211_ops ath9k_ops = { -+ #endif -+ .sw_scan_start = ath9k_sw_scan_start, -+ .sw_scan_complete = ath9k_sw_scan_complete, -+- .channel_switch_beacon = ath9k_channel_switch_beacon, -+ }; -+--- a/drivers/net/wireless/ath/ath10k/mac.c -++++ b/drivers/net/wireless/ath/ath10k/mac.c -+@@ -4142,14 +4142,6 @@ static int ath10k_set_bitrate_mask(struc -+ fixed_nss, force_sgi); -+ } - --@@ -1455,14 +1530,38 @@ skip_tx_iqcal: -- return true; -+-static void ath10k_channel_switch_beacon(struct ieee80211_hw *hw, -+- struct ieee80211_vif *vif, -+- struct cfg80211_chan_def *chandef) -+-{ -+- /* there's no need to do anything here. vif->csa_active is enough */ -+- return; -+-} -+- -+ static void ath10k_sta_rc_update(struct ieee80211_hw *hw, -+ struct ieee80211_vif *vif, -+ struct ieee80211_sta *sta, -+@@ -4256,7 +4248,6 @@ static const struct ieee80211_ops ath10k -+ .restart_complete = ath10k_restart_complete, -+ .get_survey = ath10k_get_survey, -+ .set_bitrate_mask = ath10k_set_bitrate_mask, -+- .channel_switch_beacon = ath10k_channel_switch_beacon, -+ .sta_rc_update = ath10k_sta_rc_update, -+ .get_tsf = ath10k_get_tsf, -+ #ifdef CONFIG_PM -+--- a/net/mac80211/cfg.c -++++ b/net/mac80211/cfg.c -+@@ -468,327 +468,6 @@ void sta_set_rate_info_rx(struct sta_inf -+ rinfo->flags |= RATE_INFO_FLAGS_160_MHZ_WIDTH; - } - --+static bool do_ar9003_agc_cal(struct ath_hw *ah) --+{ --+ struct ath_common *common = ath9k_hw_common(ah); --+ bool status; --+ --+ REG_WRITE(ah, AR_PHY_AGC_CONTROL, --+ REG_READ(ah, AR_PHY_AGC_CONTROL) | --+ AR_PHY_AGC_CONTROL_CAL); --+ --+ status = ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, --+ AR_PHY_AGC_CONTROL_CAL, --+ 0, AH_WAIT_TIMEOUT); --+ if (!status) { --+ ath_dbg(common, CALIBRATE, --+ "offset calibration failed to complete in %d ms," --+ "noisy environment?\n", --+ AH_WAIT_TIMEOUT / 1000); --+ return false; --+ } --+ --+ return true; --+} --+ -- static bool ar9003_hw_init_cal_soc(struct ath_hw *ah, -- struct ath9k_channel *chan) -- { -- struct ath_common *common = ath9k_hw_common(ah); -- struct ath9k_hw_cal_data *caldata = ah->caldata; -- bool txiqcal_done = false; --- bool is_reusable = true, status = true; --+ bool status = true; -- bool run_agc_cal = false, sep_iq_cal = false; --+ int i = 0; -- -- /* Use chip chainmask only for calibration */ -- ar9003_hw_set_chain_masks(ah, ah->caps.rx_chainmask, ah->caps.tx_chainmask); --@@ -1485,7 +1584,12 @@ static bool ar9003_hw_init_cal_soc(struc -- * AGC calibration. Specifically, AR9550 in SoC chips. -- */ -- if (ah->enabled_cals & TX_IQ_ON_AGC_CAL) { --- txiqcal_done = true; --+ if (REG_READ_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_0, --+ AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL)) { --+ txiqcal_done = true; --+ } else { --+ txiqcal_done = false; --+ } -- run_agc_cal = true; -- } else { -- sep_iq_cal = true; --@@ -1512,27 +1616,37 @@ skip_tx_iqcal: -- if (AR_SREV_9330_11(ah)) -- ar9003_hw_manual_peak_cal(ah, 0, IS_CHAN_2GHZ(chan)); -- --- /* Calibrate the AGC */ --- REG_WRITE(ah, AR_PHY_AGC_CONTROL, --- REG_READ(ah, AR_PHY_AGC_CONTROL) | --- AR_PHY_AGC_CONTROL_CAL); -+-static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) -+-{ -+- struct ieee80211_sub_if_data *sdata = sta->sdata; -+- struct ieee80211_local *local = sdata->local; -+- struct rate_control_ref *ref = local->rate_ctrl; -+- struct timespec uptime; -+- u64 packets = 0; -+- u32 thr = 0; -+- int i, ac; -+- -+- sinfo->generation = sdata->local->sta_generation; -+- -+- sinfo->filled = STATION_INFO_INACTIVE_TIME | -+- STATION_INFO_RX_BYTES64 | -+- STATION_INFO_TX_BYTES64 | -+- STATION_INFO_RX_PACKETS | -+- STATION_INFO_TX_PACKETS | -+- STATION_INFO_TX_RETRIES | -+- STATION_INFO_TX_FAILED | -+- STATION_INFO_TX_BITRATE | -+- STATION_INFO_RX_BITRATE | -+- STATION_INFO_RX_DROP_MISC | -+- STATION_INFO_BSS_PARAM | -+- STATION_INFO_CONNECTED_TIME | -+- STATION_INFO_STA_FLAGS | -+- STATION_INFO_BEACON_LOSS_COUNT; - - --- /* Poll for offset calibration complete */ --- status = ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, --- AR_PHY_AGC_CONTROL_CAL, --- 0, AH_WAIT_TIMEOUT); -+- do_posix_clock_monotonic_gettime(&uptime); -+- sinfo->connected_time = uptime.tv_sec - sta->last_connected; -+- -+- sinfo->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx); -+- sinfo->tx_bytes = 0; -+- for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { -+- sinfo->tx_bytes += sta->tx_bytes[ac]; -+- packets += sta->tx_packets[ac]; - - } --+ /* --+ * For non-AR9550 chips, we just trigger AGC calibration --+ * in the HW, poll for completion and then process --+ * the results. --+ * --+ * For AR955x, we run it multiple times and use --+ * median IQ correction. --+ */ --+ if (!AR_SREV_9550(ah)) { --+ status = do_ar9003_agc_cal(ah); --+ if (!status) --+ return false; -- --- if (!status) { --- ath_dbg(common, CALIBRATE, --- "offset calibration failed to complete in %d ms; noisy environment?\n", --- AH_WAIT_TIMEOUT / 1000); --- return false; --+ if (txiqcal_done) --+ ar9003_hw_tx_iq_cal_post_proc(ah, 0, false); --+ } else { --+ if (!txiqcal_done) { --+ status = do_ar9003_agc_cal(ah); --+ if (!status) --+ return false; --+ } else { --+ for (i = 0; i < MAXIQCAL; i++) { --+ status = do_ar9003_agc_cal(ah); --+ if (!status) --+ return false; --+ ar9003_hw_tx_iq_cal_post_proc(ah, i, false); --+ } --+ } --+ } -- } -- --- if (txiqcal_done) --- ar9003_hw_tx_iq_cal_post_proc(ah, is_reusable); -+- sinfo->tx_packets = packets; -+- sinfo->rx_bytes = sta->rx_bytes; -+- sinfo->rx_packets = sta->rx_packets; -+- sinfo->tx_retries = sta->tx_retry_count; -+- sinfo->tx_failed = sta->tx_retry_failed; -+- sinfo->rx_dropped_misc = sta->rx_dropped; -+- sinfo->beacon_loss_count = sta->beacon_loss_count; -+- -+- if ((sta->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) || -+- (sta->local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC)) { -+- sinfo->filled |= STATION_INFO_SIGNAL | STATION_INFO_SIGNAL_AVG; -+- if (!local->ops->get_rssi || -+- drv_get_rssi(local, sdata, &sta->sta, &sinfo->signal)) -+- sinfo->signal = (s8)sta->last_signal; -+- sinfo->signal_avg = (s8) -ewma_read(&sta->avg_signal); -+- } -+- if (sta->chains) { -+- sinfo->filled |= STATION_INFO_CHAIN_SIGNAL | -+- STATION_INFO_CHAIN_SIGNAL_AVG; -+- -+- sinfo->chains = sta->chains; -+- for (i = 0; i < ARRAY_SIZE(sinfo->chain_signal); i++) { -+- sinfo->chain_signal[i] = sta->chain_signal_last[i]; -+- sinfo->chain_signal_avg[i] = -+- (s8) -ewma_read(&sta->chain_signal_avg[i]); -+- } -+- } -+- -+- sta_set_rate_info_tx(sta, &sta->last_tx_rate, &sinfo->txrate); -+- sta_set_rate_info_rx(sta, &sinfo->rxrate); -+- -+- if (ieee80211_vif_is_mesh(&sdata->vif)) { -+-#ifdef CPTCFG_MAC80211_MESH -+- sinfo->filled |= STATION_INFO_LLID | -+- STATION_INFO_PLID | -+- STATION_INFO_PLINK_STATE | -+- STATION_INFO_LOCAL_PM | -+- STATION_INFO_PEER_PM | -+- STATION_INFO_NONPEER_PM; -+- -+- sinfo->llid = sta->llid; -+- sinfo->plid = sta->plid; -+- sinfo->plink_state = sta->plink_state; -+- if (test_sta_flag(sta, WLAN_STA_TOFFSET_KNOWN)) { -+- sinfo->filled |= STATION_INFO_T_OFFSET; -+- sinfo->t_offset = sta->t_offset; -+- } -+- sinfo->local_pm = sta->local_pm; -+- sinfo->peer_pm = sta->peer_pm; -+- sinfo->nonpeer_pm = sta->nonpeer_pm; -+-#endif -+- } -+- -+- sinfo->bss_param.flags = 0; -+- if (sdata->vif.bss_conf.use_cts_prot) -+- sinfo->bss_param.flags |= BSS_PARAM_FLAGS_CTS_PROT; -+- if (sdata->vif.bss_conf.use_short_preamble) -+- sinfo->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_PREAMBLE; -+- if (sdata->vif.bss_conf.use_short_slot) -+- sinfo->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_SLOT_TIME; -+- sinfo->bss_param.dtim_period = sdata->local->hw.conf.ps_dtim_period; -+- sinfo->bss_param.beacon_interval = sdata->vif.bss_conf.beacon_int; -+- -+- sinfo->sta_flags.set = 0; -+- sinfo->sta_flags.mask = BIT(NL80211_STA_FLAG_AUTHORIZED) | -+- BIT(NL80211_STA_FLAG_SHORT_PREAMBLE) | -+- BIT(NL80211_STA_FLAG_WME) | -+- BIT(NL80211_STA_FLAG_MFP) | -+- BIT(NL80211_STA_FLAG_AUTHENTICATED) | -+- BIT(NL80211_STA_FLAG_ASSOCIATED) | -+- BIT(NL80211_STA_FLAG_TDLS_PEER); -+- if (test_sta_flag(sta, WLAN_STA_AUTHORIZED)) -+- sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_AUTHORIZED); -+- if (test_sta_flag(sta, WLAN_STA_SHORT_PREAMBLE)) -+- sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_SHORT_PREAMBLE); -+- if (test_sta_flag(sta, WLAN_STA_WME)) -+- sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_WME); -+- if (test_sta_flag(sta, WLAN_STA_MFP)) -+- sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_MFP); -+- if (test_sta_flag(sta, WLAN_STA_AUTH)) -+- sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_AUTHENTICATED); -+- if (test_sta_flag(sta, WLAN_STA_ASSOC)) -+- sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_ASSOCIATED); -+- if (test_sta_flag(sta, WLAN_STA_TDLS_PEER)) -+- sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_TDLS_PEER); -+- -+- /* check if the driver has a SW RC implementation */ -+- if (ref && ref->ops->get_expected_throughput) -+- thr = ref->ops->get_expected_throughput(sta->rate_ctrl_priv); -+- else -+- thr = drv_get_expected_throughput(local, &sta->sta); -+- -+- if (thr != 0) { -+- sinfo->filled |= STATION_INFO_EXPECTED_THROUGHPUT; -+- sinfo->expected_throughput = thr; -+- } -+-} -+- -+-static const char ieee80211_gstrings_sta_stats[][ETH_GSTRING_LEN] = { -+- "rx_packets", "rx_bytes", "wep_weak_iv_count", -+- "rx_duplicates", "rx_fragments", "rx_dropped", -+- "tx_packets", "tx_bytes", "tx_fragments", -+- "tx_filtered", "tx_retry_failed", "tx_retries", -+- "beacon_loss", "sta_state", "txrate", "rxrate", "signal", -+- "channel", "noise", "ch_time", "ch_time_busy", -+- "ch_time_ext_busy", "ch_time_rx", "ch_time_tx" -+-}; -+-#define STA_STATS_LEN ARRAY_SIZE(ieee80211_gstrings_sta_stats) -+- -+-static int ieee80211_get_et_sset_count(struct wiphy *wiphy, -+- struct net_device *dev, -+- int sset) -+-{ -+- struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); -+- int rv = 0; -+- -+- if (sset == ETH_SS_STATS) -+- rv += STA_STATS_LEN; -+- -+- rv += drv_get_et_sset_count(sdata, sset); -+- -+- if (rv == 0) -+- return -EOPNOTSUPP; -+- return rv; -+-} -+- -+-static void ieee80211_get_et_stats(struct wiphy *wiphy, -+- struct net_device *dev, -+- struct ethtool_stats *stats, -+- u64 *data) -+-{ -+- struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); -+- struct ieee80211_chanctx_conf *chanctx_conf; -+- struct ieee80211_channel *channel; -+- struct sta_info *sta; -+- struct ieee80211_local *local = sdata->local; -+- struct station_info sinfo; -+- struct survey_info survey; -+- int i, q; -+-#define STA_STATS_SURVEY_LEN 7 -+- -+- memset(data, 0, sizeof(u64) * STA_STATS_LEN); -+- -+-#define ADD_STA_STATS(sta) \ -+- do { \ -+- data[i++] += sta->rx_packets; \ -+- data[i++] += sta->rx_bytes; \ -+- data[i++] += sta->wep_weak_iv_count; \ -+- data[i++] += sta->num_duplicates; \ -+- data[i++] += sta->rx_fragments; \ -+- data[i++] += sta->rx_dropped; \ -+- \ -+- data[i++] += sinfo.tx_packets; \ -+- data[i++] += sinfo.tx_bytes; \ -+- data[i++] += sta->tx_fragments; \ -+- data[i++] += sta->tx_filtered_count; \ -+- data[i++] += sta->tx_retry_failed; \ -+- data[i++] += sta->tx_retry_count; \ -+- data[i++] += sta->beacon_loss_count; \ -+- } while (0) -+- -+- /* For Managed stations, find the single station based on BSSID -+- * and use that. For interface types, iterate through all available -+- * stations and add stats for any station that is assigned to this -+- * network device. -+- */ -+- -+- mutex_lock(&local->sta_mtx); -+- -+- if (sdata->vif.type == NL80211_IFTYPE_STATION) { -+- sta = sta_info_get_bss(sdata, sdata->u.mgd.bssid); -+- -+- if (!(sta && !WARN_ON(sta->sdata->dev != dev))) -+- goto do_survey; -+- -+- sinfo.filled = 0; -+- sta_set_sinfo(sta, &sinfo); -+- -+- i = 0; -+- ADD_STA_STATS(sta); -+- -+- data[i++] = sta->sta_state; -+- -+- -+- if (sinfo.filled & STATION_INFO_TX_BITRATE) -+- data[i] = 100000 * -+- cfg80211_calculate_bitrate(&sinfo.txrate); -+- i++; -+- if (sinfo.filled & STATION_INFO_RX_BITRATE) -+- data[i] = 100000 * -+- cfg80211_calculate_bitrate(&sinfo.rxrate); -+- i++; -+- -+- if (sinfo.filled & STATION_INFO_SIGNAL_AVG) -+- data[i] = (u8)sinfo.signal_avg; -+- i++; -+- } else { -+- list_for_each_entry(sta, &local->sta_list, list) { -+- /* Make sure this station belongs to the proper dev */ -+- if (sta->sdata->dev != dev) -+- continue; -+- -+- sinfo.filled = 0; -+- sta_set_sinfo(sta, &sinfo); -+- i = 0; -+- ADD_STA_STATS(sta); -+- } -+- } -+- -+-do_survey: -+- i = STA_STATS_LEN - STA_STATS_SURVEY_LEN; -+- /* Get survey stats for current channel */ -+- survey.filled = 0; -+- -+- rcu_read_lock(); -+- chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); -+- if (chanctx_conf) -+- channel = chanctx_conf->def.chan; -+- else -+- channel = NULL; -+- rcu_read_unlock(); - - -- /* Revert chainmask to runtime parameters */ -- ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask); -+- if (channel) { -+- q = 0; -+- do { -+- survey.filled = 0; -+- if (drv_get_survey(local, q, &survey) != 0) { -+- survey.filled = 0; -+- break; -+- } -+- q++; -+- } while (channel != survey.channel); -+- } -+- -+- if (survey.filled) -+- data[i++] = survey.channel->center_freq; -+- else -+- data[i++] = 0; -+- if (survey.filled & SURVEY_INFO_NOISE_DBM) -+- data[i++] = (u8)survey.noise; -+- else -+- data[i++] = -1LL; -+- if (survey.filled & SURVEY_INFO_CHANNEL_TIME) -+- data[i++] = survey.channel_time; -+- else -+- data[i++] = -1LL; -+- if (survey.filled & SURVEY_INFO_CHANNEL_TIME_BUSY) -+- data[i++] = survey.channel_time_busy; -+- else -+- data[i++] = -1LL; -+- if (survey.filled & SURVEY_INFO_CHANNEL_TIME_EXT_BUSY) -+- data[i++] = survey.channel_time_ext_busy; -+- else -+- data[i++] = -1LL; -+- if (survey.filled & SURVEY_INFO_CHANNEL_TIME_RX) -+- data[i++] = survey.channel_time_rx; -+- else -+- data[i++] = -1LL; -+- if (survey.filled & SURVEY_INFO_CHANNEL_TIME_TX) -+- data[i++] = survey.channel_time_tx; -+- else -+- data[i++] = -1LL; -+- -+- mutex_unlock(&local->sta_mtx); -+- -+- if (WARN_ON(i != STA_STATS_LEN)) -+- return; -+- -+- drv_get_et_stats(sdata, stats, &(data[STA_STATS_LEN])); -+-} -+- -+-static void ieee80211_get_et_strings(struct wiphy *wiphy, -+- struct net_device *dev, -+- u32 sset, u8 *data) -+-{ -+- struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); -+- int sz_sta_stats = 0; -+- -+- if (sset == ETH_SS_STATS) { -+- sz_sta_stats = sizeof(ieee80211_gstrings_sta_stats); -+- memcpy(data, ieee80211_gstrings_sta_stats, sz_sta_stats); -+- } -+- drv_get_et_strings(sdata, sset, &(data[sz_sta_stats])); -+-} -+- -+ static int ieee80211_dump_station(struct wiphy *wiphy, struct net_device *dev, -+ int idx, u8 *mac, struct station_info *sinfo) -+ { -+@@ -875,7 +554,8 @@ static int ieee80211_set_monitor_channel -+ } -+ -+ static int ieee80211_set_probe_resp(struct ieee80211_sub_if_data *sdata, -+- const u8 *resp, size_t resp_len) -++ const u8 *resp, size_t resp_len, -++ const struct ieee80211_csa_settings *csa) -+ { -+ struct probe_resp *new, *old; - ----- a/drivers/net/wireless/rtl818x/rtl8187/rtl8187.h --+++ b/drivers/net/wireless/rtl818x/rtl8187/rtl8187.h --@@ -15,6 +15,8 @@ -- #ifndef RTL8187_H -- #define RTL8187_H -+@@ -891,6 +571,11 @@ static int ieee80211_set_probe_resp(stru -+ new->len = resp_len; -+ memcpy(new->data, resp, resp_len); - --+#include -++ if (csa) -++ memcpy(new->csa_counter_offsets, csa->counter_offsets_presp, -++ csa->n_counter_offsets_presp * -++ sizeof(new->csa_counter_offsets[0])); - + -- #include "rtl818x.h" -- #include "leds.h" -- --@@ -139,7 +141,10 @@ struct rtl8187_priv { -- u8 aifsn[4]; -- u8 rfkill_mask; -- struct { --- __le64 buf; --+ union { --+ __le64 buf; --+ u8 dummy1[L1_CACHE_BYTES]; --+ } ____cacheline_aligned; -- struct sk_buff_head queue; -- } b_tx_status; /* This queue is used by both -b and non-b devices */ -- struct mutex io_mutex; --@@ -147,7 +152,8 @@ struct rtl8187_priv { -- u8 bits8; -- __le16 bits16; -- __le32 bits32; --- } *io_dmabuf; --+ u8 dummy2[L1_CACHE_BYTES]; --+ } *io_dmabuf ____cacheline_aligned; -- bool rfkill_off; -- u16 seqno; -- }; ----- a/net/mac80211/wme.c --+++ b/net/mac80211/wme.c --@@ -154,6 +154,11 @@ u16 ieee80211_select_queue(struct ieee80 -- return IEEE80211_AC_BE; -- } -+ rcu_assign_pointer(sdata->u.ap.probe_resp, new); -+ if (old) -+ kfree_rcu(old, rcu_head); -+@@ -899,7 +584,8 @@ static int ieee80211_set_probe_resp(stru -+ } - --+ if (skb->protocol == sdata->control_port_protocol) { --+ skb->priority = 7; --+ return ieee80211_downgrade_queue(sdata, skb); -+ static int ieee80211_assign_beacon(struct ieee80211_sub_if_data *sdata, -+- struct cfg80211_beacon_data *params) -++ struct cfg80211_beacon_data *params, -++ const struct ieee80211_csa_settings *csa) -+ { -+ struct beacon_data *new, *old; -+ int new_head_len, new_tail_len; -+@@ -943,6 +629,13 @@ static int ieee80211_assign_beacon(struc -+ new->head_len = new_head_len; -+ new->tail_len = new_tail_len; -+ -++ if (csa) { -++ new->csa_current_counter = csa->count; -++ memcpy(new->csa_counter_offsets, csa->counter_offsets_beacon, -++ csa->n_counter_offsets_beacon * -++ sizeof(new->csa_counter_offsets[0])); - + } - + -- /* use the data classifier to determine what 802.1d tag the -- * data frame has */ -- rcu_read_lock(); ----- a/drivers/net/wireless/ath/ath9k/xmit.c --+++ b/drivers/net/wireless/ath/ath9k/xmit.c --@@ -1444,14 +1444,16 @@ void ath_tx_aggr_sleep(struct ieee80211_ -- for (tidno = 0, tid = &an->tid[tidno]; -- tidno < IEEE80211_NUM_TIDS; tidno++, tid++) { -- --- if (!tid->sched) --- continue; --- -- ac = tid->ac; -- txq = ac->txq; -+ /* copy in head */ -+ if (params->head) -+ memcpy(new->head, params->head, new_head_len); -+@@ -957,7 +650,7 @@ static int ieee80211_assign_beacon(struc -+ memcpy(new->tail, old->tail, new_tail_len); - -- ath_txq_lock(sc, txq); -+ err = ieee80211_set_probe_resp(sdata, params->probe_resp, -+- params->probe_resp_len); -++ params->probe_resp_len, csa); -+ if (err < 0) -+ return err; -+ if (err == 0) -+@@ -1042,7 +735,7 @@ static int ieee80211_start_ap(struct wip -+ sdata->vif.bss_conf.p2p_noa_attr.oppps_ctwindow |= -+ IEEE80211_P2P_OPPPS_ENABLE_BIT; - --+ if (!tid->sched) { --+ ath_txq_unlock(sc, txq); --+ continue; --+ } --+ -- buffered = ath_tid_has_buffered(tid); -+- err = ieee80211_assign_beacon(sdata, ¶ms->beacon); -++ err = ieee80211_assign_beacon(sdata, ¶ms->beacon, NULL); -+ if (err < 0) { -+ ieee80211_vif_release_channel(sdata); -+ return err; -+@@ -1090,7 +783,7 @@ static int ieee80211_change_beacon(struc -+ if (!old) -+ return -ENOENT; - -- tid->sched = false; --@@ -1696,7 +1698,7 @@ int ath_cabq_update(struct ath_softc *sc -+- err = ieee80211_assign_beacon(sdata, params); -++ err = ieee80211_assign_beacon(sdata, params, NULL); -+ if (err < 0) -+ return err; -+ ieee80211_bss_info_change_notify(sdata, err); -+@@ -3073,7 +2766,8 @@ static int ieee80211_set_after_csa_beaco - -- ath9k_hw_get_txq_props(sc->sc_ah, qnum, &qi); -+ switch (sdata->vif.type) { -+ case NL80211_IFTYPE_AP: -+- err = ieee80211_assign_beacon(sdata, sdata->u.ap.next_beacon); -++ err = ieee80211_assign_beacon(sdata, sdata->u.ap.next_beacon, -++ NULL); -+ kfree(sdata->u.ap.next_beacon); -+ sdata->u.ap.next_beacon = NULL; -+ -+@@ -3176,6 +2870,7 @@ static int ieee80211_set_csa_beacon(stru -+ struct cfg80211_csa_settings *params, -+ u32 *changed) -+ { -++ struct ieee80211_csa_settings csa = {}; -+ int err; - --- qi.tqi_readyTime = (cur_conf->beacon_interval * --+ qi.tqi_readyTime = (TU_TO_USEC(cur_conf->beacon_interval) * -- ATH_CABQ_READY_TIME) / 100; -- ath_txq_update(sc, qnum, &qi); -+ switch (sdata->vif.type) { -+@@ -3210,20 +2905,13 @@ static int ieee80211_set_csa_beacon(stru -+ IEEE80211_MAX_CSA_COUNTERS_NUM)) -+ return -EINVAL; - --@@ -2061,7 +2063,7 @@ static struct ath_buf *ath_tx_setup_buff -+- /* make sure we don't have garbage in other counters */ -+- memset(sdata->csa_counter_offset_beacon, 0, -+- sizeof(sdata->csa_counter_offset_beacon)); -+- memset(sdata->csa_counter_offset_presp, 0, -+- sizeof(sdata->csa_counter_offset_presp)); -+- -+- memcpy(sdata->csa_counter_offset_beacon, -+- params->counter_offsets_beacon, -+- params->n_counter_offsets_beacon * sizeof(u16)); -+- memcpy(sdata->csa_counter_offset_presp, -+- params->counter_offsets_presp, -+- params->n_counter_offsets_presp * sizeof(u16)); -++ csa.counter_offsets_beacon = params->counter_offsets_beacon; -++ csa.counter_offsets_presp = params->counter_offsets_presp; -++ csa.n_counter_offsets_beacon = params->n_counter_offsets_beacon; -++ csa.n_counter_offsets_presp = params->n_counter_offsets_presp; -++ csa.count = params->count; -+ -+- err = ieee80211_assign_beacon(sdata, ¶ms->beacon_csa); -++ err = ieee80211_assign_beacon(sdata, ¶ms->beacon_csa, &csa); -+ if (err < 0) { -+ kfree(sdata->u.ap.next_beacon); -+ return err; -+@@ -3367,7 +3055,6 @@ __ieee80211_channel_switch(struct wiphy -+ sdata->csa_radar_required = params->radar_required; -+ sdata->csa_chandef = params->chandef; -+ sdata->csa_block_tx = params->block_tx; -+- sdata->csa_current_counter = params->count; -+ sdata->vif.csa_active = true; -+ -+ if (sdata->csa_block_tx) -+@@ -3515,10 +3202,23 @@ static int ieee80211_mgmt_tx(struct wiph -+ sdata->vif.type == NL80211_IFTYPE_ADHOC) && -+ params->n_csa_offsets) { -+ int i; -+- u8 c = sdata->csa_current_counter; -++ struct beacon_data *beacon = NULL; -++ -++ rcu_read_lock(); -+ -+- for (i = 0; i < params->n_csa_offsets; i++) -+- data[params->csa_offsets[i]] = c; -++ if (sdata->vif.type == NL80211_IFTYPE_AP) -++ beacon = rcu_dereference(sdata->u.ap.beacon); -++ else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) -++ beacon = rcu_dereference(sdata->u.ibss.presp); -++ else if (ieee80211_vif_is_mesh(&sdata->vif)) -++ beacon = rcu_dereference(sdata->u.mesh.beacon); -++ -++ if (beacon) -++ for (i = 0; i < params->n_csa_offsets; i++) -++ data[params->csa_offsets[i]] = -++ beacon->csa_current_counter; -++ -++ rcu_read_unlock(); -+ } - -- ATH_TXBUF_RESET(bf); -+ IEEE80211_SKB_CB(skb)->flags = flags; -+@@ -3598,21 +3298,6 @@ static int ieee80211_get_antenna(struct -+ return drv_get_antenna(local, tx_ant, rx_ant); -+ } - --- if (tid) { --+ if (tid && ieee80211_is_data_present(hdr->frame_control)) { -- fragno = le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG; -- seqno = tid->seq_next; -- hdr->seq_ctrl = cpu_to_le16(tid->seq_next << IEEE80211_SEQ_SEQ_SHIFT); --@@ -2184,14 +2186,15 @@ int ath_tx_start(struct ieee80211_hw *hw -- txq->stopped = true; -- } -+-static int ieee80211_set_ringparam(struct wiphy *wiphy, u32 tx, u32 rx) -+-{ -+- struct ieee80211_local *local = wiphy_priv(wiphy); -+- -+- return drv_set_ringparam(local, tx, rx); -+-} -+- -+-static void ieee80211_get_ringparam(struct wiphy *wiphy, -+- u32 *tx, u32 *tx_max, u32 *rx, u32 *rx_max) -+-{ -+- struct ieee80211_local *local = wiphy_priv(wiphy); -+- -+- drv_get_ringparam(local, tx, tx_max, rx, rx_max); -+-} -+- -+ static int ieee80211_set_rekey_data(struct wiphy *wiphy, -+ struct net_device *dev, -+ struct cfg80211_gtk_rekey_data *data) -+@@ -3844,8 +3529,6 @@ const struct cfg80211_ops mac80211_confi -+ .mgmt_frame_register = ieee80211_mgmt_frame_register, -+ .set_antenna = ieee80211_set_antenna, -+ .get_antenna = ieee80211_get_antenna, -+- .set_ringparam = ieee80211_set_ringparam, -+- .get_ringparam = ieee80211_get_ringparam, -+ .set_rekey_data = ieee80211_set_rekey_data, -+ .tdls_oper = ieee80211_tdls_oper, -+ .tdls_mgmt = ieee80211_tdls_mgmt, -+@@ -3854,9 +3537,6 @@ const struct cfg80211_ops mac80211_confi -+ #ifdef CONFIG_PM -+ .set_wakeup = ieee80211_set_wakeup, -+ #endif -+- .get_et_sset_count = ieee80211_get_et_sset_count, -+- .get_et_stats = ieee80211_get_et_stats, -+- .get_et_strings = ieee80211_get_et_strings, -+ .get_channel = ieee80211_cfg_get_channel, -+ .start_radar_detection = ieee80211_start_radar_detection, -+ .channel_switch = ieee80211_channel_switch, -+--- a/net/mac80211/debugfs_sta.c -++++ b/net/mac80211/debugfs_sta.c -+@@ -587,7 +587,6 @@ void ieee80211_sta_debugfs_add(struct st -+ DEBUGFS_ADD_COUNTER(tx_filtered, tx_filtered_count); -+ DEBUGFS_ADD_COUNTER(tx_retry_failed, tx_retry_failed); -+ DEBUGFS_ADD_COUNTER(tx_retry_count, tx_retry_count); -+- DEBUGFS_ADD_COUNTER(wep_weak_iv_count, wep_weak_iv_count); -+ -+ if (sizeof(sta->driver_buffered_tids) == sizeof(u32)) -+ debugfs_create_x32("driver_buffered_tids", 0400, -+--- a/net/mac80211/wep.c -++++ b/net/mac80211/wep.c -+@@ -271,22 +271,6 @@ static int ieee80211_wep_decrypt(struct -+ return ret; -+ } - --+ if (txctl->an && ieee80211_is_data_present(hdr->frame_control)) --+ tid = ath_get_skb_tid(sc, txctl->an, skb); --+ -- if (info->flags & IEEE80211_TX_CTL_PS_RESPONSE) { -- ath_txq_unlock(sc, txq); -- txq = sc->tx.uapsdq; -- ath_txq_lock(sc, txq); -- } else if (txctl->an && -- ieee80211_is_data_present(hdr->frame_control)) { --- tid = ath_get_skb_tid(sc, txctl->an, skb); - - -- WARN_ON(tid->ac->txq != txctl->txq); -- -- if (info->flags & IEEE80211_TX_CTL_CLEAR_PS_FILT) ----- a/drivers/net/wireless/ath/ath9k/init.c --+++ b/drivers/net/wireless/ath/ath9k/init.c --@@ -943,6 +943,7 @@ static void ath9k_set_hw_capab(struct at -- hw->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL; -- hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_5_10_MHZ; -- hw->wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH; --+ hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD; -- -- hw->queues = 4; -- hw->max_rates = 4; ----- a/net/mac80211/ieee80211_i.h --+++ b/net/mac80211/ieee80211_i.h --@@ -1700,14 +1700,8 @@ void ieee80211_stop_queue_by_reason(stru -- void ieee80211_propagate_queue_wake(struct ieee80211_local *local, int queue); -- void ieee80211_add_pending_skb(struct ieee80211_local *local, -- struct sk_buff *skb); ---void ieee80211_add_pending_skbs_fn(struct ieee80211_local *local, --- struct sk_buff_head *skbs, --- void (*fn)(void *data), void *data); ---static inline void ieee80211_add_pending_skbs(struct ieee80211_local *local, --- struct sk_buff_head *skbs) -+-static bool ieee80211_wep_is_weak_iv(struct sk_buff *skb, -+- struct ieee80211_key *key) - -{ --- ieee80211_add_pending_skbs_fn(local, skbs, NULL, NULL); -+- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; -+- unsigned int hdrlen; -+- u8 *ivpos; -+- u32 iv; -+- -+- hdrlen = ieee80211_hdrlen(hdr->frame_control); -+- ivpos = skb->data + hdrlen; -+- iv = (ivpos[0] << 16) | (ivpos[1] << 8) | ivpos[2]; -+- -+- return ieee80211_wep_weak_iv(iv, key->conf.keylen); - -} --+void ieee80211_add_pending_skbs(struct ieee80211_local *local, --+ struct sk_buff_head *skbs); -- void ieee80211_flush_queues(struct ieee80211_local *local, -- struct ieee80211_sub_if_data *sdata); -+- -+ ieee80211_rx_result -+ ieee80211_crypto_wep_decrypt(struct ieee80211_rx_data *rx) -+ { -+@@ -301,16 +285,12 @@ ieee80211_crypto_wep_decrypt(struct ieee -+ if (!(status->flag & RX_FLAG_DECRYPTED)) { -+ if (skb_linearize(rx->skb)) -+ return RX_DROP_UNUSABLE; -+- if (rx->sta && ieee80211_wep_is_weak_iv(rx->skb, rx->key)) -+- rx->sta->wep_weak_iv_count++; -+ if (ieee80211_wep_decrypt(rx->local, rx->skb, rx->key)) -+ return RX_DROP_UNUSABLE; -+ } else if (!(status->flag & RX_FLAG_IV_STRIPPED)) { -+ if (!pskb_may_pull(rx->skb, ieee80211_hdrlen(fc) + -+ IEEE80211_WEP_IV_LEN)) -+ return RX_DROP_UNUSABLE; -+- if (rx->sta && ieee80211_wep_is_weak_iv(rx->skb, rx->key)) -+- rx->sta->wep_weak_iv_count++; -+ ieee80211_wep_remove_iv(rx->local, rx->skb, rx->key); -+ /* remove ICV */ -+ if (pskb_trim(rx->skb, rx->skb->len - IEEE80211_WEP_ICV_LEN)) -+--- a/include/net/cfg80211.h -++++ b/include/net/cfg80211.h -+@@ -2278,16 +2278,6 @@ struct cfg80211_qos_map { -+ * -+ * @set_noack_map: Set the NoAck Map for the TIDs. -+ * -+- * @get_et_sset_count: Ethtool API to get string-set count. -+- * See @ethtool_ops.get_sset_count -+- * -+- * @get_et_stats: Ethtool API to get a set of u64 stats. -+- * See @ethtool_ops.get_ethtool_stats -+- * -+- * @get_et_strings: Ethtool API to get a set of strings to describe stats -+- * and perhaps other supported types of ethtool data-sets. -+- * See @ethtool_ops.get_strings -+- * -+ * @get_channel: Get the current operating channel for the virtual interface. -+ * For monitor interfaces, it should return %NULL unless there's a single -+ * current monitoring channel. -+@@ -2529,13 +2519,6 @@ struct cfg80211_ops { -+ struct net_device *dev, -+ u16 noack_map); -+ -+- int (*get_et_sset_count)(struct wiphy *wiphy, -+- struct net_device *dev, int sset); -+- void (*get_et_stats)(struct wiphy *wiphy, struct net_device *dev, -+- struct ethtool_stats *stats, u64 *data); -+- void (*get_et_strings)(struct wiphy *wiphy, struct net_device *dev, -+- u32 sset, u8 *data); -+- -+ int (*get_channel)(struct wiphy *wiphy, -+ struct wireless_dev *wdev, -+ struct cfg80211_chan_def *chandef); -+@@ -4846,6 +4829,10 @@ void cfg80211_stop_iface(struct wiphy *w -+ */ -+ void cfg80211_shutdown_all_interfaces(struct wiphy *wiphy); - ----- a/net/mac80211/sta_info.c --+++ b/net/mac80211/sta_info.c --@@ -91,7 +91,7 @@ static int sta_info_hash_del(struct ieee -- return -ENOENT; -- } -++ -++/* ethtool helper */ -++void cfg80211_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info); -++ -+ /* Logging, debugging and troubleshooting/diagnostic helpers. */ -+ -+ /* wiphy_printk helpers, similar to dev_printk */ -+--- a/net/mac80211/Makefile -++++ b/net/mac80211/Makefile -+@@ -17,6 +17,7 @@ mac80211-y := \ -+ aes_ccm.o \ -+ aes_cmac.o \ -+ cfg.o \ -++ ethtool.o \ -+ rx.o \ -+ spectmgmt.o \ -+ tx.o \ -+--- a/net/mac80211/ieee80211_i.h -++++ b/net/mac80211/ieee80211_i.h -+@@ -229,16 +229,29 @@ struct ieee80211_rx_data { -+ u16 tkip_iv16; -+ }; -+ -++struct ieee80211_csa_settings { -++ const u16 *counter_offsets_beacon; -++ const u16 *counter_offsets_presp; -++ -++ int n_counter_offsets_beacon; -++ int n_counter_offsets_presp; -++ -++ u8 count; -++}; -++ -+ struct beacon_data { -+ u8 *head, *tail; -+ int head_len, tail_len; -+ struct ieee80211_meshconf_ie *meshconf; -++ u16 csa_counter_offsets[IEEE80211_MAX_CSA_COUNTERS_NUM]; -++ u8 csa_current_counter; -+ struct rcu_head rcu_head; -+ }; -+ -+ struct probe_resp { -+ struct rcu_head rcu_head; -+ int len; -++ u16 csa_counter_offsets[IEEE80211_MAX_CSA_COUNTERS_NUM]; -+ u8 data[0]; -+ }; - ---static void cleanup_single_sta(struct sta_info *sta) --+static void __cleanup_single_sta(struct sta_info *sta) -- { -- int ac, i; -- struct tid_ampdu_tx *tid_tx; --@@ -99,7 +99,8 @@ static void cleanup_single_sta(struct st -- struct ieee80211_local *local = sdata->local; -- struct ps_data *ps; -+@@ -754,8 +767,6 @@ struct ieee80211_sub_if_data { -+ struct mac80211_qos_map __rcu *qos_map; - --- if (test_sta_flag(sta, WLAN_STA_PS_STA)) { --+ if (test_sta_flag(sta, WLAN_STA_PS_STA) || --+ test_sta_flag(sta, WLAN_STA_PS_DRIVER)) { -- if (sta->sdata->vif.type == NL80211_IFTYPE_AP || -- sta->sdata->vif.type == NL80211_IFTYPE_AP_VLAN) -- ps = &sdata->bss->ps; --@@ -109,6 +110,7 @@ static void cleanup_single_sta(struct st -- return; -+ struct work_struct csa_finalize_work; -+- u16 csa_counter_offset_beacon[IEEE80211_MAX_CSA_COUNTERS_NUM]; -+- u16 csa_counter_offset_presp[IEEE80211_MAX_CSA_COUNTERS_NUM]; -+ bool csa_radar_required; -+ bool csa_block_tx; /* write-protected by sdata_lock and local->mtx */ -+ struct cfg80211_chan_def csa_chandef; -+@@ -767,7 +778,6 @@ struct ieee80211_sub_if_data { -+ struct ieee80211_chanctx *reserved_chanctx; -+ struct cfg80211_chan_def reserved_chandef; -+ bool reserved_radar_required; -+- u8 csa_current_counter; - -- clear_sta_flag(sta, WLAN_STA_PS_STA); --+ clear_sta_flag(sta, WLAN_STA_PS_DRIVER); -+ /* used to reconfigure hardware SM PS */ -+ struct work_struct recalc_smps; -+@@ -1850,6 +1860,8 @@ int ieee80211_tdls_oper(struct wiphy *wi -+ const u8 *peer, enum nl80211_tdls_operation oper); - -- atomic_dec(&ps->num_sta_ps); -- sta_info_recalc_tim(sta); --@@ -139,7 +141,14 @@ static void cleanup_single_sta(struct st -- ieee80211_purge_tx_queue(&local->hw, &tid_tx->pending); -- kfree(tid_tx); -- } --+} - --+static void cleanup_single_sta(struct sta_info *sta) --+{ --+ struct ieee80211_sub_if_data *sdata = sta->sdata; --+ struct ieee80211_local *local = sdata->local; -++extern const struct ethtool_ops ieee80211_ethtool_ops; - + --+ __cleanup_single_sta(sta); -- sta_info_free(local, sta); -- } -+ #ifdef CPTCFG_MAC80211_NOINLINE -+ #define debug_noinline noinline -+ #else -+--- a/net/mac80211/iface.c -++++ b/net/mac80211/iface.c -+@@ -399,6 +399,7 @@ int ieee80211_add_virtual_monitor(struct -+ sdata->vif.type = NL80211_IFTYPE_MONITOR; -+ snprintf(sdata->name, IFNAMSIZ, "%s-monitor", -+ wiphy_name(local->hw.wiphy)); -++ sdata->wdev.iftype = NL80211_IFTYPE_MONITOR; - --@@ -330,6 +339,7 @@ struct sta_info *sta_info_alloc(struct i -- rcu_read_unlock(); -+ sdata->encrypt_headroom = IEEE80211_ENCRYPT_HEADROOM; - -- spin_lock_init(&sta->lock); --+ spin_lock_init(&sta->ps_lock); -- INIT_WORK(&sta->drv_unblock_wk, sta_unblock); -- INIT_WORK(&sta->ampdu_mlme.work, ieee80211_ba_session_work); -- mutex_init(&sta->ampdu_mlme.mtx); --@@ -487,21 +497,26 @@ static int sta_info_insert_finish(struct -- goto out_err; -- } -+@@ -1303,6 +1304,7 @@ static void ieee80211_setup_sdata(struct -+ sdata->control_port_protocol = cpu_to_be16(ETH_P_PAE); -+ sdata->control_port_no_encrypt = false; -+ sdata->encrypt_headroom = IEEE80211_ENCRYPT_HEADROOM; -++ sdata->vif.bss_conf.idle = true; - --- /* notify driver */ --- err = sta_info_insert_drv_state(local, sdata, sta); --- if (err) --- goto out_err; --- -- local->num_sta++; -- local->sta_generation++; -- smp_mb(); -+ sdata->noack_map = 0; - --+ /* simplify things and don't accept BA sessions yet */ --+ set_sta_flag(sta, WLAN_STA_BLOCK_BA); --+ -- /* make the station visible */ -- sta_info_hash_add(local, sta); -+@@ -1721,6 +1723,8 @@ int ieee80211_if_add(struct ieee80211_lo - -- list_add_rcu(&sta->list, &local->sta_list); -+ ndev->features |= local->hw.netdev_features; - --+ /* notify driver */ --+ err = sta_info_insert_drv_state(local, sdata, sta); --+ if (err) --+ goto out_remove; -++ netdev_set_default_ethtool_ops(ndev, &ieee80211_ethtool_ops); - + -- set_sta_flag(sta, WLAN_STA_INSERTED); --+ /* accept BA sessions now */ --+ clear_sta_flag(sta, WLAN_STA_BLOCK_BA); -+ ret = register_netdevice(ndev); -+ if (ret) { -+ free_netdev(ndev); -+--- a/net/wireless/core.c -++++ b/net/wireless/core.c -+@@ -25,7 +25,6 @@ -+ #include "sysfs.h" -+ #include "debugfs.h" -+ #include "wext-compat.h" -+-#include "ethtool.h" -+ #include "rdev-ops.h" - -- ieee80211_recalc_min_chandef(sdata); -- ieee80211_sta_debugfs_add(sta); --@@ -522,6 +537,12 @@ static int sta_info_insert_finish(struct -- mesh_accept_plinks_update(sdata); -+ /* name for sysfs, %d is appended */ -+@@ -940,8 +939,6 @@ static int cfg80211_netdev_notifier_call -+ /* allow mac80211 to determine the timeout */ -+ wdev->ps_timeout = -1; - -- return 0; --+ out_remove: --+ sta_info_hash_del(local, sta); --+ list_del_rcu(&sta->list); --+ local->num_sta--; --+ synchronize_net(); --+ __cleanup_single_sta(sta); -- out_err: -- mutex_unlock(&local->sta_mtx); -- rcu_read_lock(); --@@ -1071,10 +1092,14 @@ struct ieee80211_sta *ieee80211_find_sta -- } -- EXPORT_SYMBOL(ieee80211_find_sta); -+- netdev_set_default_ethtool_ops(dev, &cfg80211_ethtool_ops); -+- -+ if ((wdev->iftype == NL80211_IFTYPE_STATION || -+ wdev->iftype == NL80211_IFTYPE_P2P_CLIENT || -+ wdev->iftype == NL80211_IFTYPE_ADHOC) && !wdev->use_4addr) -+--- a/net/wireless/ethtool.c -++++ b/net/wireless/ethtool.c -+@@ -1,11 +1,9 @@ -+ #include -+ #include -+ #include "core.h" -+-#include "ethtool.h" -+ #include "rdev-ops.h" - ---static void clear_sta_ps_flags(void *_sta) --+/* powersave support code */ --+void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta) -+-static void cfg80211_get_drvinfo(struct net_device *dev, -+- struct ethtool_drvinfo *info) -++void cfg80211_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) - { --- struct sta_info *sta = _sta; -- struct ieee80211_sub_if_data *sdata = sta->sdata; --+ struct ieee80211_local *local = sdata->local; --+ struct sk_buff_head pending; --+ int filtered = 0, buffered = 0, ac; --+ unsigned long flags; -- struct ps_data *ps; -- -- if (sdata->vif.type == NL80211_IFTYPE_AP || --@@ -1085,20 +1110,6 @@ static void clear_sta_ps_flags(void *_st -- else -- return; -+ struct wireless_dev *wdev = dev->ieee80211_ptr; - --- clear_sta_flag(sta, WLAN_STA_PS_DRIVER); --- if (test_and_clear_sta_flag(sta, WLAN_STA_PS_STA)) --- atomic_dec(&ps->num_sta_ps); -+@@ -23,84 +21,4 @@ static void cfg80211_get_drvinfo(struct -+ strlcpy(info->bus_info, dev_name(wiphy_dev(wdev->wiphy)), -+ sizeof(info->bus_info)); -+ } -+- -+-static int cfg80211_get_regs_len(struct net_device *dev) -+-{ -+- /* For now, return 0... */ -+- return 0; - -} - - ---/* powersave support code */ ---void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta) -+-static void cfg80211_get_regs(struct net_device *dev, struct ethtool_regs *regs, -+- void *data) - -{ --- struct ieee80211_sub_if_data *sdata = sta->sdata; --- struct ieee80211_local *local = sdata->local; --- struct sk_buff_head pending; --- int filtered = 0, buffered = 0, ac; --- unsigned long flags; -+- struct wireless_dev *wdev = dev->ieee80211_ptr; - - -- clear_sta_flag(sta, WLAN_STA_SP); -- -- BUILD_BUG_ON(BITS_TO_LONGS(IEEE80211_NUM_TIDS) > 1); --@@ -1109,6 +1120,8 @@ void ieee80211_sta_ps_deliver_wakeup(str -+- regs->version = wdev->wiphy->hw_version; -+- regs->len = 0; -+-} -+- -+-static void cfg80211_get_ringparam(struct net_device *dev, -+- struct ethtool_ringparam *rp) -+-{ -+- struct wireless_dev *wdev = dev->ieee80211_ptr; -+- struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); -+- -+- memset(rp, 0, sizeof(*rp)); -+- -+- if (rdev->ops->get_ringparam) -+- rdev_get_ringparam(rdev, &rp->tx_pending, &rp->tx_max_pending, -+- &rp->rx_pending, &rp->rx_max_pending); -+-} -+- -+-static int cfg80211_set_ringparam(struct net_device *dev, -+- struct ethtool_ringparam *rp) -+-{ -+- struct wireless_dev *wdev = dev->ieee80211_ptr; -+- struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); -+- -+- if (rp->rx_mini_pending != 0 || rp->rx_jumbo_pending != 0) -+- return -EINVAL; -+- -+- if (rdev->ops->set_ringparam) -+- return rdev_set_ringparam(rdev, rp->tx_pending, rp->rx_pending); -+- -+- return -ENOTSUPP; -+-} -+- -+-static int cfg80211_get_sset_count(struct net_device *dev, int sset) -+-{ -+- struct wireless_dev *wdev = dev->ieee80211_ptr; -+- struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); -+- if (rdev->ops->get_et_sset_count) -+- return rdev_get_et_sset_count(rdev, dev, sset); -+- return -EOPNOTSUPP; -+-} -+- -+-static void cfg80211_get_stats(struct net_device *dev, -+- struct ethtool_stats *stats, u64 *data) -+-{ -+- struct wireless_dev *wdev = dev->ieee80211_ptr; -+- struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); -+- if (rdev->ops->get_et_stats) -+- rdev_get_et_stats(rdev, dev, stats, data); -+-} -+- -+-static void cfg80211_get_strings(struct net_device *dev, u32 sset, u8 *data) -+-{ -+- struct wireless_dev *wdev = dev->ieee80211_ptr; -+- struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); -+- if (rdev->ops->get_et_strings) -+- rdev_get_et_strings(rdev, dev, sset, data); -+-} -+- -+-const struct ethtool_ops cfg80211_ethtool_ops = { -+- .get_drvinfo = cfg80211_get_drvinfo, -+- .get_regs_len = cfg80211_get_regs_len, -+- .get_regs = cfg80211_get_regs, -+- .get_link = ethtool_op_get_link, -+- .get_ringparam = cfg80211_get_ringparam, -+- .set_ringparam = cfg80211_set_ringparam, -+- .get_strings = cfg80211_get_strings, -+- .get_ethtool_stats = cfg80211_get_stats, -+- .get_sset_count = cfg80211_get_sset_count, -+-}; -++EXPORT_SYMBOL(cfg80211_get_drvinfo); -+--- a/net/wireless/ethtool.h -++++ /dev/null -+@@ -1,6 +0,0 @@ -+-#ifndef __CFG80211_ETHTOOL__ -+-#define __CFG80211_ETHTOOL__ -+- -+-extern const struct ethtool_ops cfg80211_ethtool_ops; -+- -+-#endif /* __CFG80211_ETHTOOL__ */ -+--- a/net/wireless/rdev-ops.h -++++ b/net/wireless/rdev-ops.h -+@@ -714,25 +714,6 @@ static inline int rdev_get_antenna(struc -+ return ret; -+ } - -- skb_queue_head_init(&pending); -+-static inline int rdev_set_ringparam(struct cfg80211_registered_device *rdev, -+- u32 tx, u32 rx) -+-{ -+- int ret; -+- trace_rdev_set_ringparam(&rdev->wiphy, tx, rx); -+- ret = rdev->ops->set_ringparam(&rdev->wiphy, tx, rx); -+- trace_rdev_return_int(&rdev->wiphy, ret); -+- return ret; -+-} -+- -+-static inline void rdev_get_ringparam(struct cfg80211_registered_device *rdev, -+- u32 *tx, u32 *tx_max, u32 *rx, -+- u32 *rx_max) -+-{ -+- trace_rdev_get_ringparam(&rdev->wiphy); -+- rdev->ops->get_ringparam(&rdev->wiphy, tx, tx_max, rx, rx_max); -+- trace_rdev_return_void_tx_rx(&rdev->wiphy, *tx, *tx_max, *rx, *rx_max); -+-} -+- -+ static inline int -+ rdev_sched_scan_start(struct cfg80211_registered_device *rdev, -+ struct net_device *dev, -+@@ -816,35 +797,6 @@ static inline int rdev_set_noack_map(str -+ } - --+ /* sync with ieee80211_tx_h_unicast_ps_buf */ --+ spin_lock(&sta->ps_lock); -- /* Send all buffered frames to the station */ -- for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { -- int count = skb_queue_len(&pending), tmp; --@@ -1127,7 +1140,12 @@ void ieee80211_sta_ps_deliver_wakeup(str -- buffered += tmp - count; -- } -+ static inline int -+-rdev_get_et_sset_count(struct cfg80211_registered_device *rdev, -+- struct net_device *dev, int sset) -+-{ -+- int ret; -+- trace_rdev_get_et_sset_count(&rdev->wiphy, dev, sset); -+- ret = rdev->ops->get_et_sset_count(&rdev->wiphy, dev, sset); -+- trace_rdev_return_int(&rdev->wiphy, ret); -+- return ret; -+-} -+- -+-static inline void rdev_get_et_stats(struct cfg80211_registered_device *rdev, -+- struct net_device *dev, -+- struct ethtool_stats *stats, u64 *data) -+-{ -+- trace_rdev_get_et_stats(&rdev->wiphy, dev); -+- rdev->ops->get_et_stats(&rdev->wiphy, dev, stats, data); -+- trace_rdev_return_void(&rdev->wiphy); -+-} -+- -+-static inline void rdev_get_et_strings(struct cfg80211_registered_device *rdev, -+- struct net_device *dev, u32 sset, -+- u8 *data) -+-{ -+- trace_rdev_get_et_strings(&rdev->wiphy, dev, sset); -+- rdev->ops->get_et_strings(&rdev->wiphy, dev, sset, data); -+- trace_rdev_return_void(&rdev->wiphy); -+-} -+- -+-static inline int -+ rdev_get_channel(struct cfg80211_registered_device *rdev, -+ struct wireless_dev *wdev, -+ struct cfg80211_chan_def *chandef) -+--- a/net/wireless/trace.h -++++ b/net/wireless/trace.h -+@@ -298,11 +298,6 @@ DEFINE_EVENT(wiphy_only_evt, rdev_return -+ TP_ARGS(wiphy) -+ ); - --- ieee80211_add_pending_skbs_fn(local, &pending, clear_sta_ps_flags, sta); --+ ieee80211_add_pending_skbs(local, &pending); --+ clear_sta_flag(sta, WLAN_STA_PS_DRIVER); --+ clear_sta_flag(sta, WLAN_STA_PS_STA); --+ spin_unlock(&sta->ps_lock); --+ --+ atomic_dec(&ps->num_sta_ps); -+-DEFINE_EVENT(wiphy_only_evt, rdev_get_ringparam, -+- TP_PROTO(struct wiphy *wiphy), -+- TP_ARGS(wiphy) -+-); -+- -+ DEFINE_EVENT(wiphy_only_evt, rdev_get_antenna, -+ TP_PROTO(struct wiphy *wiphy), -+ TP_ARGS(wiphy) -+@@ -580,11 +575,6 @@ DEFINE_EVENT(wiphy_netdev_evt, rdev_stop -+ TP_ARGS(wiphy, netdev) -+ ); - -- /* This station just woke up and isn't aware of our SMPS state */ -- if (!ieee80211_smps_is_restrictive(sta->known_smps_mode, ----- a/net/mac80211/sta_info.h --+++ b/net/mac80211/sta_info.h --@@ -267,6 +267,7 @@ struct ieee80211_tx_latency_stat { -- * @drv_unblock_wk: used for driver PS unblocking -- * @listen_interval: listen interval of this station, when we're acting as AP -- * @_flags: STA flags, see &enum ieee80211_sta_info_flags, do not use directly --+ * @ps_lock: used for powersave (when mac80211 is the AP) related locking -- * @ps_tx_buf: buffers (per AC) of frames to transmit to this station -- * when it leaves power saving state or polls -- * @tx_filtered: buffers (per AC) of frames we already tried to --@@ -356,10 +357,8 @@ struct sta_info { -- /* use the accessors defined below */ -- unsigned long _flags; -- --- /* --- * STA powersave frame queues, no more than the internal --- * locking required. --- */ --+ /* STA powersave lock and frame queues */ --+ spinlock_t ps_lock; -- struct sk_buff_head ps_tx_buf[IEEE80211_NUM_ACS]; -- struct sk_buff_head tx_filtered[IEEE80211_NUM_ACS]; -- unsigned long driver_buffered_tids; ----- a/net/mac80211/util.c --+++ b/net/mac80211/util.c --@@ -435,9 +435,8 @@ void ieee80211_add_pending_skb(struct ie -- spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); -- } -+-DEFINE_EVENT(wiphy_netdev_evt, rdev_get_et_stats, -+- TP_PROTO(struct wiphy *wiphy, struct net_device *netdev), -+- TP_ARGS(wiphy, netdev) -+-); -+- -+ DEFINE_EVENT(wiphy_netdev_evt, rdev_sched_scan_stop, -+ TP_PROTO(struct wiphy *wiphy, struct net_device *netdev), -+ TP_ARGS(wiphy, netdev) -+@@ -1439,11 +1429,6 @@ DECLARE_EVENT_CLASS(tx_rx_evt, -+ WIPHY_PR_ARG, __entry->tx, __entry->rx) -+ ); - ---void ieee80211_add_pending_skbs_fn(struct ieee80211_local *local, --- struct sk_buff_head *skbs, --- void (*fn)(void *data), void *data) --+void ieee80211_add_pending_skbs(struct ieee80211_local *local, --+ struct sk_buff_head *skbs) -- { -- struct ieee80211_hw *hw = &local->hw; -- struct sk_buff *skb; --@@ -461,9 +460,6 @@ void ieee80211_add_pending_skbs_fn(struc -- __skb_queue_tail(&local->pending[queue], skb); -- } -+-DEFINE_EVENT(tx_rx_evt, rdev_set_ringparam, -+- TP_PROTO(struct wiphy *wiphy, u32 tx, u32 rx), -+- TP_ARGS(wiphy, rx, tx) -+-); -+- -+ DEFINE_EVENT(tx_rx_evt, rdev_set_antenna, -+ TP_PROTO(struct wiphy *wiphy, u32 tx, u32 rx), -+ TP_ARGS(wiphy, rx, tx) -+@@ -1725,40 +1710,6 @@ TRACE_EVENT(rdev_set_noack_map, -+ WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->noack_map) -+ ); - --- if (fn) --- fn(data); -+-TRACE_EVENT(rdev_get_et_sset_count, -+- TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, int sset), -+- TP_ARGS(wiphy, netdev, sset), -+- TP_STRUCT__entry( -+- WIPHY_ENTRY -+- NETDEV_ENTRY -+- __field(int, sset) -+- ), -+- TP_fast_assign( -+- WIPHY_ASSIGN; -+- NETDEV_ASSIGN; -+- __entry->sset = sset; -+- ), -+- TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", sset: %d", -+- WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->sset) -+-); - - -- for (i = 0; i < hw->queues; i++) -- __ieee80211_wake_queue(hw, i, -- IEEE80211_QUEUE_STOP_REASON_SKB_ADD); ----- a/net/wireless/reg.c --+++ b/net/wireless/reg.c --@@ -1700,7 +1700,7 @@ static void reg_process_hint(struct regu -- return; -- case NL80211_REGDOM_SET_BY_USER: -- treatment = reg_process_hint_user(reg_request); --- if (treatment == REG_REQ_OK || --+ if (treatment == REG_REQ_IGNORE || -- treatment == REG_REQ_ALREADY_SET) -- return; -- schedule_delayed_work(®_timeout, msecs_to_jiffies(3142)); ----- a/drivers/net/wireless/ath/ath9k/debug.c --+++ b/drivers/net/wireless/ath/ath9k/debug.c --@@ -138,43 +138,41 @@ static ssize_t read_file_ani(struct file -- unsigned int len = 0, size = 1024; -- ssize_t retval = 0; -- char *buf; --+ int i; --+ struct { --+ const char *name; --+ unsigned int val; --+ } ani_info[] = { --+ { "ANI RESET", ah->stats.ast_ani_reset }, --+ { "OFDM LEVEL", ah->ani.ofdmNoiseImmunityLevel }, --+ { "CCK LEVEL", ah->ani.cckNoiseImmunityLevel }, --+ { "SPUR UP", ah->stats.ast_ani_spurup }, --+ { "SPUR DOWN", ah->stats.ast_ani_spurup }, --+ { "OFDM WS-DET ON", ah->stats.ast_ani_ofdmon }, --+ { "OFDM WS-DET OFF", ah->stats.ast_ani_ofdmoff }, --+ { "MRC-CCK ON", ah->stats.ast_ani_ccklow }, --+ { "MRC-CCK OFF", ah->stats.ast_ani_cckhigh }, --+ { "FIR-STEP UP", ah->stats.ast_ani_stepup }, --+ { "FIR-STEP DOWN", ah->stats.ast_ani_stepdown }, --+ { "INV LISTENTIME", ah->stats.ast_ani_lneg_or_lzero }, --+ { "OFDM ERRORS", ah->stats.ast_ani_ofdmerrs }, --+ { "CCK ERRORS", ah->stats.ast_ani_cckerrs }, --+ }; -- -- buf = kzalloc(size, GFP_KERNEL); -- if (buf == NULL) -- return -ENOMEM; -- --- if (common->disable_ani) { --- len += scnprintf(buf + len, size - len, "%s: %s\n", --- "ANI", "DISABLED"); --+ len += scnprintf(buf + len, size - len, "%15s: %s\n", "ANI", --+ common->disable_ani ? "DISABLED" : "ENABLED"); -+-TRACE_EVENT(rdev_get_et_strings, -+- TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, u32 sset), -+- TP_ARGS(wiphy, netdev, sset), -+- TP_STRUCT__entry( -+- WIPHY_ENTRY -+- NETDEV_ENTRY -+- __field(u32, sset) -+- ), -+- TP_fast_assign( -+- WIPHY_ASSIGN; -+- NETDEV_ASSIGN; -+- __entry->sset = sset; -+- ), -+- TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", sset: %u", -+- WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->sset) -+-); -+- -+ DEFINE_EVENT(wiphy_wdev_evt, rdev_get_channel, -+ TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev), -+ TP_ARGS(wiphy, wdev) -+--- /dev/null -++++ b/net/mac80211/ethtool.c -+@@ -0,0 +1,244 @@ -++/* -++ * mac80211 ethtool hooks for cfg80211 -++ * -++ * Copied from cfg.c - originally -++ * Copyright 2006-2010 Johannes Berg -++ * Copyright 2014 Intel Corporation (Author: Johannes Berg) -++ * -++ * This file is GPLv2 as found in COPYING. -++ */ -++#include -++#include -++#include "ieee80211_i.h" -++#include "sta_info.h" -++#include "driver-ops.h" -++ -++static int ieee80211_set_ringparam(struct net_device *dev, -++ struct ethtool_ringparam *rp) -++{ -++ struct ieee80211_local *local = wiphy_priv(dev->ieee80211_ptr->wiphy); - + --+ if (common->disable_ani) -- goto exit; --- } -- --- len += scnprintf(buf + len, size - len, "%15s: %s\n", --- "ANI", "ENABLED"); --- len += scnprintf(buf + len, size - len, "%15s: %u\n", --- "ANI RESET", ah->stats.ast_ani_reset); --- len += scnprintf(buf + len, size - len, "%15s: %u\n", --- "SPUR UP", ah->stats.ast_ani_spurup); --- len += scnprintf(buf + len, size - len, "%15s: %u\n", --- "SPUR DOWN", ah->stats.ast_ani_spurup); --- len += scnprintf(buf + len, size - len, "%15s: %u\n", --- "OFDM WS-DET ON", ah->stats.ast_ani_ofdmon); --- len += scnprintf(buf + len, size - len, "%15s: %u\n", --- "OFDM WS-DET OFF", ah->stats.ast_ani_ofdmoff); --- len += scnprintf(buf + len, size - len, "%15s: %u\n", --- "MRC-CCK ON", ah->stats.ast_ani_ccklow); --- len += scnprintf(buf + len, size - len, "%15s: %u\n", --- "MRC-CCK OFF", ah->stats.ast_ani_cckhigh); --- len += scnprintf(buf + len, size - len, "%15s: %u\n", --- "FIR-STEP UP", ah->stats.ast_ani_stepup); --- len += scnprintf(buf + len, size - len, "%15s: %u\n", --- "FIR-STEP DOWN", ah->stats.ast_ani_stepdown); --- len += scnprintf(buf + len, size - len, "%15s: %u\n", --- "INV LISTENTIME", ah->stats.ast_ani_lneg_or_lzero); --- len += scnprintf(buf + len, size - len, "%15s: %u\n", --- "OFDM ERRORS", ah->stats.ast_ani_ofdmerrs); --- len += scnprintf(buf + len, size - len, "%15s: %u\n", --- "CCK ERRORS", ah->stats.ast_ani_cckerrs); --+ for (i = 0; i < ARRAY_SIZE(ani_info); i++) --+ len += scnprintf(buf + len, size - len, "%15s: %u\n", --+ ani_info[i].name, ani_info[i].val); -++ if (rp->rx_mini_pending != 0 || rp->rx_jumbo_pending != 0) -++ return -EINVAL; - + -- exit: -- if (len > size) -- len = size; --@@ -866,6 +864,12 @@ static ssize_t read_file_reset(struct fi -- "%17s: %2d\n", "PLL RX Hang", -- sc->debug.stats.reset[RESET_TYPE_PLL_HANG]); -- len += scnprintf(buf + len, sizeof(buf) - len, --+ "%17s: %2d\n", "MAC Hang", --+ sc->debug.stats.reset[RESET_TYPE_MAC_HANG]); --+ len += scnprintf(buf + len, sizeof(buf) - len, --+ "%17s: %2d\n", "Stuck Beacon", --+ sc->debug.stats.reset[RESET_TYPE_BEACON_STUCK]); --+ len += scnprintf(buf + len, sizeof(buf) - len, -- "%17s: %2d\n", "MCI Reset", -- sc->debug.stats.reset[RESET_TYPE_MCI]); -- ----- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c --+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c --@@ -868,10 +868,6 @@ static void ar9003_hw_set_rfmode(struct -- -- if (IS_CHAN_A_FAST_CLOCK(ah, chan)) -- rfMode |= (AR_PHY_MODE_DYNAMIC | AR_PHY_MODE_DYN_CCK_DISABLE); --- if (IS_CHAN_QUARTER_RATE(chan)) --- rfMode |= AR_PHY_MODE_QUARTER; --- if (IS_CHAN_HALF_RATE(chan)) --- rfMode |= AR_PHY_MODE_HALF; -- -- if (rfMode & (AR_PHY_MODE_QUARTER | AR_PHY_MODE_HALF)) -- REG_RMW_FIELD(ah, AR_PHY_FRAME_CTL, ----- a/drivers/net/wireless/ath/ath5k/mac80211-ops.c --+++ b/drivers/net/wireless/ath/ath5k/mac80211-ops.c --@@ -706,6 +706,7 @@ ath5k_get_survey(struct ieee80211_hw *hw -- survey->channel = conf->chandef.chan; -- survey->noise = ah->ah_noise_floor; -- survey->filled = SURVEY_INFO_NOISE_DBM | --+ SURVEY_INFO_IN_USE | -- SURVEY_INFO_CHANNEL_TIME | -- SURVEY_INFO_CHANNEL_TIME_BUSY | -- SURVEY_INFO_CHANNEL_TIME_RX | ----- a/drivers/net/wireless/ath/ath9k/recv.c --+++ b/drivers/net/wireless/ath/ath9k/recv.c --@@ -732,11 +732,18 @@ static struct ath_rxbuf *ath_get_next_rx -- return NULL; -- -- /* --- * mark descriptor as zero-length and set the 'more' --- * flag to ensure that both buffers get discarded --+ * Re-check previous descriptor, in case it has been filled --+ * in the mean time. -- */ --- rs->rs_datalen = 0; --- rs->rs_more = true; --+ ret = ath9k_hw_rxprocdesc(ah, ds, rs); --+ if (ret == -EINPROGRESS) { --+ /* --+ * mark descriptor as zero-length and set the 'more' --+ * flag to ensure that both buffers get discarded --+ */ --+ rs->rs_datalen = 0; --+ rs->rs_more = true; --+ } -- } -- -- list_del(&bf->list); --@@ -985,32 +992,32 @@ static int ath9k_rx_skb_preprocess(struc -- struct ath_common *common = ath9k_hw_common(ah); -- struct ieee80211_hdr *hdr; -- bool discard_current = sc->rx.discard_next; --- int ret = 0; -- -- /* -- * Discard corrupt descriptors which are marked in -- * ath_get_next_rx_buf(). -- */ --- sc->rx.discard_next = rx_stats->rs_more; -- if (discard_current) --- return -EINVAL; --+ goto corrupt; -++ return drv_set_ringparam(local, rp->tx_pending, rp->rx_pending); -++} - + --+ sc->rx.discard_next = false; -- -- /* -- * Discard zero-length packets. -- */ -- if (!rx_stats->rs_datalen) { -- RX_STAT_INC(rx_len_err); --- return -EINVAL; --+ goto corrupt; -- } -- --- /* --- * rs_status follows rs_datalen so if rs_datalen is too large --- * we can take a hint that hardware corrupted it, so ignore --- * those frames. --- */ --+ /* --+ * rs_status follows rs_datalen so if rs_datalen is too large --+ * we can take a hint that hardware corrupted it, so ignore --+ * those frames. -++static void ieee80211_get_ringparam(struct net_device *dev, -++ struct ethtool_ringparam *rp) -++{ -++ struct ieee80211_local *local = wiphy_priv(dev->ieee80211_ptr->wiphy); -++ -++ memset(rp, 0, sizeof(*rp)); -++ -++ drv_get_ringparam(local, &rp->tx_pending, &rp->tx_max_pending, -++ &rp->rx_pending, &rp->rx_max_pending); -++} -++ -++static const char ieee80211_gstrings_sta_stats[][ETH_GSTRING_LEN] = { -++ "rx_packets", "rx_bytes", -++ "rx_duplicates", "rx_fragments", "rx_dropped", -++ "tx_packets", "tx_bytes", "tx_fragments", -++ "tx_filtered", "tx_retry_failed", "tx_retries", -++ "beacon_loss", "sta_state", "txrate", "rxrate", "signal", -++ "channel", "noise", "ch_time", "ch_time_busy", -++ "ch_time_ext_busy", "ch_time_rx", "ch_time_tx" -++}; -++#define STA_STATS_LEN ARRAY_SIZE(ieee80211_gstrings_sta_stats) -++ -++static int ieee80211_get_sset_count(struct net_device *dev, int sset) -++{ -++ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); -++ int rv = 0; -++ -++ if (sset == ETH_SS_STATS) -++ rv += STA_STATS_LEN; -++ -++ rv += drv_get_et_sset_count(sdata, sset); -++ -++ if (rv == 0) -++ return -EOPNOTSUPP; -++ return rv; -++} -++ -++static void ieee80211_get_stats(struct net_device *dev, -++ struct ethtool_stats *stats, -++ u64 *data) -++{ -++ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); -++ struct ieee80211_chanctx_conf *chanctx_conf; -++ struct ieee80211_channel *channel; -++ struct sta_info *sta; -++ struct ieee80211_local *local = sdata->local; -++ struct station_info sinfo; -++ struct survey_info survey; -++ int i, q; -++#define STA_STATS_SURVEY_LEN 7 -++ -++ memset(data, 0, sizeof(u64) * STA_STATS_LEN); -++ -++#define ADD_STA_STATS(sta) \ -++ do { \ -++ data[i++] += sta->rx_packets; \ -++ data[i++] += sta->rx_bytes; \ -++ data[i++] += sta->num_duplicates; \ -++ data[i++] += sta->rx_fragments; \ -++ data[i++] += sta->rx_dropped; \ -++ \ -++ data[i++] += sinfo.tx_packets; \ -++ data[i++] += sinfo.tx_bytes; \ -++ data[i++] += sta->tx_fragments; \ -++ data[i++] += sta->tx_filtered_count; \ -++ data[i++] += sta->tx_retry_failed; \ -++ data[i++] += sta->tx_retry_count; \ -++ data[i++] += sta->beacon_loss_count; \ -++ } while (0) -++ -++ /* For Managed stations, find the single station based on BSSID -++ * and use that. For interface types, iterate through all available -++ * stations and add stats for any station that is assigned to this -++ * network device. - + */ -- if (rx_stats->rs_datalen > (common->rx_bufsize - ah->caps.rx_status_len)) { -- RX_STAT_INC(rx_len_err); --- return -EINVAL; --+ goto corrupt; -++ -++ mutex_lock(&local->sta_mtx); -++ -++ if (sdata->vif.type == NL80211_IFTYPE_STATION) { -++ sta = sta_info_get_bss(sdata, sdata->u.mgd.bssid); -++ -++ if (!(sta && !WARN_ON(sta->sdata->dev != dev))) -++ goto do_survey; -++ -++ sinfo.filled = 0; -++ sta_set_sinfo(sta, &sinfo); -++ -++ i = 0; -++ ADD_STA_STATS(sta); -++ -++ data[i++] = sta->sta_state; -++ -++ -++ if (sinfo.filled & STATION_INFO_TX_BITRATE) -++ data[i] = 100000 * -++ cfg80211_calculate_bitrate(&sinfo.txrate); -++ i++; -++ if (sinfo.filled & STATION_INFO_RX_BITRATE) -++ data[i] = 100000 * -++ cfg80211_calculate_bitrate(&sinfo.rxrate); -++ i++; -++ -++ if (sinfo.filled & STATION_INFO_SIGNAL_AVG) -++ data[i] = (u8)sinfo.signal_avg; -++ i++; -++ } else { -++ list_for_each_entry(sta, &local->sta_list, list) { -++ /* Make sure this station belongs to the proper dev */ -++ if (sta->sdata->dev != dev) -++ continue; -++ -++ sinfo.filled = 0; -++ sta_set_sinfo(sta, &sinfo); -++ i = 0; -++ ADD_STA_STATS(sta); -++ } -++ } -++ -++do_survey: -++ i = STA_STATS_LEN - STA_STATS_SURVEY_LEN; -++ /* Get survey stats for current channel */ -++ survey.filled = 0; -++ -++ rcu_read_lock(); -++ chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); -++ if (chanctx_conf) -++ channel = chanctx_conf->def.chan; -++ else -++ channel = NULL; -++ rcu_read_unlock(); -++ -++ if (channel) { -++ q = 0; -++ do { -++ survey.filled = 0; -++ if (drv_get_survey(local, q, &survey) != 0) { -++ survey.filled = 0; -++ break; -++ } -++ q++; -++ } while (channel != survey.channel); -++ } -++ -++ if (survey.filled) -++ data[i++] = survey.channel->center_freq; -++ else -++ data[i++] = 0; -++ if (survey.filled & SURVEY_INFO_NOISE_DBM) -++ data[i++] = (u8)survey.noise; -++ else -++ data[i++] = -1LL; -++ if (survey.filled & SURVEY_INFO_CHANNEL_TIME) -++ data[i++] = survey.channel_time; -++ else -++ data[i++] = -1LL; -++ if (survey.filled & SURVEY_INFO_CHANNEL_TIME_BUSY) -++ data[i++] = survey.channel_time_busy; -++ else -++ data[i++] = -1LL; -++ if (survey.filled & SURVEY_INFO_CHANNEL_TIME_EXT_BUSY) -++ data[i++] = survey.channel_time_ext_busy; -++ else -++ data[i++] = -1LL; -++ if (survey.filled & SURVEY_INFO_CHANNEL_TIME_RX) -++ data[i++] = survey.channel_time_rx; -++ else -++ data[i++] = -1LL; -++ if (survey.filled & SURVEY_INFO_CHANNEL_TIME_TX) -++ data[i++] = survey.channel_time_tx; -++ else -++ data[i++] = -1LL; -++ -++ mutex_unlock(&local->sta_mtx); -++ -++ if (WARN_ON(i != STA_STATS_LEN)) -++ return; -++ -++ drv_get_et_stats(sdata, stats, &(data[STA_STATS_LEN])); -++} -++ -++static void ieee80211_get_strings(struct net_device *dev, u32 sset, u8 *data) -++{ -++ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); -++ int sz_sta_stats = 0; -++ -++ if (sset == ETH_SS_STATS) { -++ sz_sta_stats = sizeof(ieee80211_gstrings_sta_stats); -++ memcpy(data, ieee80211_gstrings_sta_stats, sz_sta_stats); -++ } -++ drv_get_et_strings(sdata, sset, &(data[sz_sta_stats])); -++} -++ -++static int ieee80211_get_regs_len(struct net_device *dev) -++{ -++ return 0; -++} -++ -++static void ieee80211_get_regs(struct net_device *dev, -++ struct ethtool_regs *regs, -++ void *data) -++{ -++ struct wireless_dev *wdev = dev->ieee80211_ptr; -++ -++ regs->version = wdev->wiphy->hw_version; -++ regs->len = 0; -++} -++ -++const struct ethtool_ops ieee80211_ethtool_ops = { -++ .get_drvinfo = cfg80211_get_drvinfo, -++ .get_regs_len = ieee80211_get_regs_len, -++ .get_regs = ieee80211_get_regs, -++ .get_link = ethtool_op_get_link, -++ .get_ringparam = ieee80211_get_ringparam, -++ .set_ringparam = ieee80211_set_ringparam, -++ .get_strings = ieee80211_get_strings, -++ .get_ethtool_stats = ieee80211_get_stats, -++ .get_sset_count = ieee80211_get_sset_count, -++}; -+--- a/net/mac80211/ibss.c -++++ b/net/mac80211/ibss.c -+@@ -143,7 +143,7 @@ ieee80211_ibss_build_presp(struct ieee80 -+ *pos++ = csa_settings->block_tx ? 1 : 0; -+ *pos++ = ieee80211_frequency_to_channel( -+ csa_settings->chandef.chan->center_freq); -+- sdata->csa_counter_offset_beacon[0] = (pos - presp->head); -++ presp->csa_counter_offsets[0] = (pos - presp->head); -+ *pos++ = csa_settings->count; - } - -- /* Only use status info from the last fragment */ --@@ -1024,10 +1031,8 @@ static int ath9k_rx_skb_preprocess(struc -- * This is different from the other corrupt descriptor -- * condition handled above. -- */ --- if (rx_stats->rs_status & ATH9K_RXERR_CORRUPT_DESC) { --- ret = -EINVAL; --- goto exit; --- } --+ if (rx_stats->rs_status & ATH9K_RXERR_CORRUPT_DESC) --+ goto corrupt; -- -- hdr = (struct ieee80211_hdr *) (skb->data + ah->caps.rx_status_len); -- --@@ -1043,18 +1048,15 @@ static int ath9k_rx_skb_preprocess(struc -- if (ath_process_fft(sc, hdr, rx_stats, rx_status->mactime)) -- RX_STAT_INC(rx_spectral); -+@@ -1677,6 +1677,7 @@ int ieee80211_ibss_join(struct ieee80211 -+ sdata->u.ibss.control_port = params->control_port; -+ sdata->u.ibss.userspace_handles_dfs = params->userspace_handles_dfs; -+ sdata->u.ibss.basic_rates = params->basic_rates; -++ sdata->u.ibss.last_scan_completed = jiffies; - --- ret = -EINVAL; --- goto exit; --+ return -EINVAL; -+ /* fix basic_rates if channel does not support these rates */ -+ rate_flags = ieee80211_chandef_rate_flags(¶ms->chandef); -+--- a/net/mac80211/mesh.c -++++ b/net/mac80211/mesh.c -+@@ -679,7 +679,7 @@ ieee80211_mesh_build_beacon(struct ieee8 -+ *pos++ = 0x0; -+ *pos++ = ieee80211_frequency_to_channel( -+ csa->settings.chandef.chan->center_freq); -+- sdata->csa_counter_offset_beacon[0] = hdr_len + 6; -++ bcn->csa_counter_offsets[0] = hdr_len + 6; -+ *pos++ = csa->settings.count; -+ *pos++ = WLAN_EID_CHAN_SWITCH_PARAM; -+ *pos++ = 6; -+--- a/net/wireless/genregdb.awk -++++ b/net/wireless/genregdb.awk -+@@ -65,17 +65,7 @@ function parse_reg_rule() -+ sub(/,/, "", units) -+ dfs_cac = $9 -+ if (units == "mW") { -+- if (power == 100) { -+- power = 20 -+- } else if (power == 200) { -+- power = 23 -+- } else if (power == 500) { -+- power = 27 -+- } else if (power == 1000) { -+- power = 30 -+- } else { -+- print "Unknown power value in database!" -+- } -++ power = 10 * log(power)/log(10) -+ } else { -+ dfs_cac = $8 - } -+@@ -114,7 +104,7 @@ function parse_reg_rule() - -- /* -- * everything but the rate is checked here, the rate check is done -- * separately to avoid doing two lookups for a rate for each frame. -- */ --- if (!ath9k_rx_accept(common, hdr, rx_status, rx_stats, decrypt_error)) { --- ret = -EINVAL; --- goto exit; --- } --+ if (!ath9k_rx_accept(common, hdr, rx_status, rx_stats, decrypt_error)) --+ return -EINVAL; -- -- if (ath_is_mybeacon(common, hdr)) { -- RX_STAT_INC(rx_beacons); --@@ -1064,15 +1066,11 @@ static int ath9k_rx_skb_preprocess(struc -- /* -- * This shouldn't happen, but have a safety check anyway. -- */ --- if (WARN_ON(!ah->curchan)) { --- ret = -EINVAL; --- goto exit; --- } --+ if (WARN_ON(!ah->curchan)) --+ return -EINVAL; -- --- if (ath9k_process_rate(common, hw, rx_stats, rx_status)) { --- ret =-EINVAL; --- goto exit; --- } --+ if (ath9k_process_rate(common, hw, rx_stats, rx_status)) --+ return -EINVAL; -- -- ath9k_process_rssi(common, hw, rx_stats, rx_status); -+ } -+ flags = flags "0" -+- printf "\t\tREG_RULE_EXT(%d, %d, %d, %d, %d, %d, %s),\n", start, end, bw, gain, power, dfs_cac, flags -++ printf "\t\tREG_RULE_EXT(%d, %d, %d, %d, %.0f, %d, %s),\n", start, end, bw, gain, power, dfs_cac, flags -+ rules++ -+ } - --@@ -1087,9 +1085,11 @@ static int ath9k_rx_skb_preprocess(struc -- sc->rx.num_pkts++; -- #endif -+--- a/net/mac80211/debugfs_netdev.c -++++ b/net/mac80211/debugfs_netdev.c -+@@ -34,8 +34,7 @@ static ssize_t ieee80211_if_read( -+ ssize_t ret = -EINVAL; - ---exit: --- sc->rx.discard_next = false; --- return ret; --+ return 0; --+ --+corrupt: --+ sc->rx.discard_next = rx_stats->rs_more; --+ return -EINVAL; -- } -+ read_lock(&dev_base_lock); -+- if (sdata->dev->reg_state == NETREG_REGISTERED) -+- ret = (*format)(sdata, buf, sizeof(buf)); -++ ret = (*format)(sdata, buf, sizeof(buf)); -+ read_unlock(&dev_base_lock); - -- static void ath9k_rx_skb_postprocess(struct ath_common *common, ----- a/drivers/net/wireless/ath/ath9k/ani.c --+++ b/drivers/net/wireless/ath/ath9k/ani.c --@@ -176,16 +176,26 @@ static void ath9k_hw_set_ofdm_nil(struct -- if (ah->opmode == NL80211_IFTYPE_STATION && -- BEACON_RSSI(ah) <= ATH9K_ANI_RSSI_THR_HIGH) -- weak_sig = true; --- -- /* --- * OFDM Weak signal detection is always enabled for AP mode. --+ * Newer chipsets are better at dealing with high PHY error counts - --+ * keep weak signal detection enabled when no RSSI threshold is --+ * available to determine if it is needed (mode != STA) -- */ --- if (ah->opmode != NL80211_IFTYPE_AP && --- aniState->ofdmWeakSigDetect != weak_sig) { --- ath9k_hw_ani_control(ah, --- ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION, --- entry_ofdm->ofdm_weak_signal_on); --- } --+ else if (AR_SREV_9300_20_OR_LATER(ah) && --+ ah->opmode != NL80211_IFTYPE_STATION) --+ weak_sig = true; --+ --+ /* Older chipsets are more sensitive to high PHY error counts */ --+ else if (!AR_SREV_9300_20_OR_LATER(ah) && --+ aniState->ofdmNoiseImmunityLevel >= 8) --+ weak_sig = false; --+ --+ if (aniState->ofdmWeakSigDetect != weak_sig) --+ ath9k_hw_ani_control(ah, ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION, --+ weak_sig); --+ --+ if (!AR_SREV_9300_20_OR_LATER(ah)) --+ return; -+ if (ret >= 0) -+@@ -62,8 +61,7 @@ static ssize_t ieee80211_if_write( - -- if (aniState->ofdmNoiseImmunityLevel >= ATH9K_ANI_OFDM_DEF_LEVEL) { -- ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH; --@@ -308,17 +318,6 @@ void ath9k_ani_reset(struct ath_hw *ah, -- BUG_ON(aniState == NULL); -- ah->stats.ast_ani_reset++; -- --- /* only allow a subset of functions in AP mode */ --- if (ah->opmode == NL80211_IFTYPE_AP) { --- if (IS_CHAN_2GHZ(chan)) { --- ah->ani_function = (ATH9K_ANI_SPUR_IMMUNITY_LEVEL | --- ATH9K_ANI_FIRSTEP_LEVEL); --- if (AR_SREV_9300_20_OR_LATER(ah)) --- ah->ani_function |= ATH9K_ANI_MRC_CCK; --- } else --- ah->ani_function = 0; --- } --- -- ofdm_nil = max_t(int, ATH9K_ANI_OFDM_DEF_LEVEL, -- aniState->ofdmNoiseImmunityLevel); -- cck_nil = max_t(int, ATH9K_ANI_CCK_DEF_LEVEL, --@@ -483,10 +482,17 @@ void ath9k_hw_ani_init(struct ath_hw *ah -- -- ath_dbg(common, ANI, "Initialize ANI\n"); -- --- ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH; --- ah->config.ofdm_trig_low = ATH9K_ANI_OFDM_TRIG_LOW; --- ah->config.cck_trig_high = ATH9K_ANI_CCK_TRIG_HIGH; --- ah->config.cck_trig_low = ATH9K_ANI_CCK_TRIG_LOW; --+ if (AR_SREV_9300_20_OR_LATER(ah)) { --+ ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH; --+ ah->config.ofdm_trig_low = ATH9K_ANI_OFDM_TRIG_LOW; --+ ah->config.cck_trig_high = ATH9K_ANI_CCK_TRIG_HIGH; --+ ah->config.cck_trig_low = ATH9K_ANI_CCK_TRIG_LOW; --+ } else { --+ ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH_OLD; --+ ah->config.ofdm_trig_low = ATH9K_ANI_OFDM_TRIG_LOW_OLD; --+ ah->config.cck_trig_high = ATH9K_ANI_CCK_TRIG_HIGH_OLD; --+ ah->config.cck_trig_low = ATH9K_ANI_CCK_TRIG_LOW_OLD; --+ } -+ ret = -ENODEV; -+ rtnl_lock(); -+- if (sdata->dev->reg_state == NETREG_REGISTERED) -+- ret = (*write)(sdata, buf, count); -++ ret = (*write)(sdata, buf, count); -+ rtnl_unlock(); - -- ani->spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL; -- ani->firstepLevel = ATH9K_ANI_FIRSTEP_LVL; ----- a/drivers/net/wireless/ath/ath9k/ani.h --+++ b/drivers/net/wireless/ath/ath9k/ani.h --@@ -22,12 +22,16 @@ -- /* units are errors per second */ -- #define ATH9K_ANI_OFDM_TRIG_HIGH 3500 -- #define ATH9K_ANI_OFDM_TRIG_HIGH_BELOW_INI 1000 --+#define ATH9K_ANI_OFDM_TRIG_HIGH_OLD 500 -- -- #define ATH9K_ANI_OFDM_TRIG_LOW 400 -- #define ATH9K_ANI_OFDM_TRIG_LOW_ABOVE_INI 900 --+#define ATH9K_ANI_OFDM_TRIG_LOW_OLD 200 -- -- #define ATH9K_ANI_CCK_TRIG_HIGH 600 --+#define ATH9K_ANI_CCK_TRIG_HIGH_OLD 200 -- #define ATH9K_ANI_CCK_TRIG_LOW 300 --+#define ATH9K_ANI_CCK_TRIG_LOW_OLD 100 -- -- #define ATH9K_ANI_SPUR_IMMUNE_LVL 3 -- #define ATH9K_ANI_FIRSTEP_LVL 2 ----- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c --+++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c --@@ -26,10 +26,6 @@ static const int firstep_table[] = -- /* level: 0 1 2 3 4 5 6 7 8 */ -- { -4, -2, 0, 2, 4, 6, 8, 10, 12 }; /* lvl 0-8, default 2 */ -- ---static const int cycpwrThr1_table[] = ---/* level: 0 1 2 3 4 5 6 7 8 */ --- { -6, -4, -2, 0, 2, 4, 6, 8 }; /* lvl 0-7, default 3 */ --- -- /* -- * register values to turn OFDM weak signal detection OFF -- */ --@@ -921,7 +917,7 @@ static bool ar5008_hw_ani_control_new(st -- struct ath_common *common = ath9k_hw_common(ah); -- struct ath9k_channel *chan = ah->curchan; -- struct ar5416AniState *aniState = &ah->ani; --- s32 value, value2; --+ s32 value; -- -- switch (cmd & ah->ani_function) { -- case ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION:{ --@@ -1008,42 +1004,9 @@ static bool ar5008_hw_ani_control_new(st -- case ATH9K_ANI_FIRSTEP_LEVEL:{ -- u32 level = param; -- --- if (level >= ARRAY_SIZE(firstep_table)) { --- ath_dbg(common, ANI, --- "ATH9K_ANI_FIRSTEP_LEVEL: level out of range (%u > %zu)\n", --- level, ARRAY_SIZE(firstep_table)); --- return false; --- } --- --- /* --- * make register setting relative to default --- * from INI file & cap value --- */ --- value = firstep_table[level] - --- firstep_table[ATH9K_ANI_FIRSTEP_LVL] + --- aniState->iniDef.firstep; --- if (value < ATH9K_SIG_FIRSTEP_SETTING_MIN) --- value = ATH9K_SIG_FIRSTEP_SETTING_MIN; --- if (value > ATH9K_SIG_FIRSTEP_SETTING_MAX) --- value = ATH9K_SIG_FIRSTEP_SETTING_MAX; --+ value = level; -- REG_RMW_FIELD(ah, AR_PHY_FIND_SIG, --- AR_PHY_FIND_SIG_FIRSTEP, --- value); --- /* --- * we need to set first step low register too --- * make register setting relative to default --- * from INI file & cap value --- */ --- value2 = firstep_table[level] - --- firstep_table[ATH9K_ANI_FIRSTEP_LVL] + --- aniState->iniDef.firstepLow; --- if (value2 < ATH9K_SIG_FIRSTEP_SETTING_MIN) --- value2 = ATH9K_SIG_FIRSTEP_SETTING_MIN; --- if (value2 > ATH9K_SIG_FIRSTEP_SETTING_MAX) --- value2 = ATH9K_SIG_FIRSTEP_SETTING_MAX; --- --- REG_RMW_FIELD(ah, AR_PHY_FIND_SIG_LOW, --- AR_PHY_FIND_SIG_FIRSTEP_LOW, value2); --+ AR_PHY_FIND_SIG_FIRSTEP, value); -- -- if (level != aniState->firstepLevel) { -- ath_dbg(common, ANI, --@@ -1060,7 +1023,7 @@ static bool ar5008_hw_ani_control_new(st -- aniState->firstepLevel, -- level, -- ATH9K_ANI_FIRSTEP_LVL, --- value2, --+ value, -- aniState->iniDef.firstepLow); -- if (level > aniState->firstepLevel) -- ah->stats.ast_ani_stepup++; --@@ -1073,41 +1036,13 @@ static bool ar5008_hw_ani_control_new(st -- case ATH9K_ANI_SPUR_IMMUNITY_LEVEL:{ -- u32 level = param; -- --- if (level >= ARRAY_SIZE(cycpwrThr1_table)) { --- ath_dbg(common, ANI, --- "ATH9K_ANI_SPUR_IMMUNITY_LEVEL: level out of range (%u > %zu)\n", --- level, ARRAY_SIZE(cycpwrThr1_table)); --- return false; --- } --- /* --- * make register setting relative to default --- * from INI file & cap value --- */ --- value = cycpwrThr1_table[level] - --- cycpwrThr1_table[ATH9K_ANI_SPUR_IMMUNE_LVL] + --- aniState->iniDef.cycpwrThr1; --- if (value < ATH9K_SIG_SPUR_IMM_SETTING_MIN) --- value = ATH9K_SIG_SPUR_IMM_SETTING_MIN; --- if (value > ATH9K_SIG_SPUR_IMM_SETTING_MAX) --- value = ATH9K_SIG_SPUR_IMM_SETTING_MAX; --+ value = (level + 1) * 2; -- REG_RMW_FIELD(ah, AR_PHY_TIMING5, --- AR_PHY_TIMING5_CYCPWR_THR1, --- value); --+ AR_PHY_TIMING5_CYCPWR_THR1, value); -- --- /* --- * set AR_PHY_EXT_CCA for extension channel --- * make register setting relative to default --- * from INI file & cap value --- */ --- value2 = cycpwrThr1_table[level] - --- cycpwrThr1_table[ATH9K_ANI_SPUR_IMMUNE_LVL] + --- aniState->iniDef.cycpwrThr1Ext; --- if (value2 < ATH9K_SIG_SPUR_IMM_SETTING_MIN) --- value2 = ATH9K_SIG_SPUR_IMM_SETTING_MIN; --- if (value2 > ATH9K_SIG_SPUR_IMM_SETTING_MAX) --- value2 = ATH9K_SIG_SPUR_IMM_SETTING_MAX; --- REG_RMW_FIELD(ah, AR_PHY_EXT_CCA, --- AR_PHY_EXT_TIMING5_CYCPWR_THR1, value2); --+ if (IS_CHAN_HT40(ah->curchan)) --+ REG_RMW_FIELD(ah, AR_PHY_EXT_CCA, --+ AR_PHY_EXT_TIMING5_CYCPWR_THR1, value); -- -- if (level != aniState->spurImmunityLevel) { -- ath_dbg(common, ANI, --@@ -1124,7 +1059,7 @@ static bool ar5008_hw_ani_control_new(st -- aniState->spurImmunityLevel, -- level, -- ATH9K_ANI_SPUR_IMMUNE_LVL, --- value2, --+ value, -- aniState->iniDef.cycpwrThr1Ext); -- if (level > aniState->spurImmunityLevel) -- ah->stats.ast_ani_spurup++; -+ return ret; -diff --git a/package/mac80211/patches/310-ap_scan.patch b/package/mac80211/patches/310-ap_scan.patch -index 389a003..23ecd37 100644 ---- a/package/mac80211/patches/310-ap_scan.patch -+++ b/package/mac80211/patches/310-ap_scan.patch -@@ -1,6 +1,6 @@ - --- a/net/mac80211/cfg.c - +++ b/net/mac80211/cfg.c --@@ -2148,7 +2148,7 @@ static int ieee80211_scan(struct wiphy * -+@@ -1903,7 +1903,7 @@ static int ieee80211_scan(struct wiphy * - * the frames sent while scanning on other channel will be - * lost) - */ -diff --git a/package/mac80211/patches/400-ath_move_debug_code.patch b/package/mac80211/patches/400-ath_move_debug_code.patch -index 0dba7ac..4cc77af 100644 ---- a/package/mac80211/patches/400-ath_move_debug_code.patch -+++ b/package/mac80211/patches/400-ath_move_debug_code.patch -@@ -12,7 +12,7 @@ - ccflags-y += -D__CHECK_ENDIAN__ - --- a/drivers/net/wireless/ath/ath.h - +++ b/drivers/net/wireless/ath/ath.h --@@ -282,13 +282,6 @@ void _ath_dbg(struct ath_common *common, -+@@ -295,13 +295,6 @@ void _ath_dbg(struct ath_common *common, - #endif /* CPTCFG_ATH_DEBUG */ - - /** Returns string describing opmode, or NULL if unknown mode. */ -diff --git a/package/mac80211/patches/403-ath_regd_optional.patch b/package/mac80211/patches/403-ath_regd_optional.patch -index 07c54cc..808e729 100644 ---- a/package/mac80211/patches/403-ath_regd_optional.patch -+++ b/package/mac80211/patches/403-ath_regd_optional.patch -@@ -58,7 +58,7 @@ - ---help--- - --- a/.local-symbols - +++ b/.local-symbols --@@ -119,6 +119,7 @@ RTL8187_LEDS= -+@@ -116,6 +116,7 @@ RTL8187_LEDS= - ATH_COMMON= - ATH_CARDS= - ATH_DEBUG= -diff --git a/package/mac80211/patches/405-regd_no_assoc_hints.patch b/package/mac80211/patches/405-regd_no_assoc_hints.patch -index 6ad4fda..2152433 100644 ---- a/package/mac80211/patches/405-regd_no_assoc_hints.patch -+++ b/package/mac80211/patches/405-regd_no_assoc_hints.patch -@@ -1,6 +1,6 @@ - --- a/net/wireless/reg.c - +++ b/net/wireless/reg.c --@@ -1878,6 +1878,8 @@ void regulatory_hint_country_ie(struct w -+@@ -2080,6 +2080,8 @@ void regulatory_hint_country_ie(struct w - enum environment_cap env = ENVIRON_ANY; - struct regulatory_request *request = NULL, *lr; - -@@ -9,7 +9,7 @@ - /* IE len must be evenly divisible by 2 */ - if (country_ie_len & 0x01) - return; --@@ -2072,6 +2074,7 @@ static void restore_regulatory_settings( -+@@ -2276,6 +2278,7 @@ static void restore_regulatory_settings( - - void regulatory_hint_disconnect(void) - { -diff --git a/package/mac80211/patches/410-ath9k_allow_adhoc_and_ap.patch b/package/mac80211/patches/410-ath9k_allow_adhoc_and_ap.patch -index 1f71e0b..ce752f1 100644 ---- a/package/mac80211/patches/410-ath9k_allow_adhoc_and_ap.patch -+++ b/package/mac80211/patches/410-ath9k_allow_adhoc_and_ap.patch -@@ -1,8 +1,8 @@ - --- a/drivers/net/wireless/ath/ath9k/init.c - +++ b/drivers/net/wireless/ath/ath9k/init.c --@@ -866,6 +866,7 @@ static const struct ieee80211_iface_limi -- #endif -- BIT(NL80211_IFTYPE_AP) | -+@@ -655,6 +655,7 @@ static const struct ieee80211_iface_limi -+ BIT(NL80211_IFTYPE_AP) }, -+ { .max = 1, .types = BIT(NL80211_IFTYPE_P2P_CLIENT) | - BIT(NL80211_IFTYPE_P2P_GO) }, - + { .max = 1, .types = BIT(NL80211_IFTYPE_ADHOC) }, - }; -diff --git a/package/mac80211/patches/411-ath5k_allow_adhoc_and_ap.patch b/package/mac80211/patches/411-ath5k_allow_adhoc_and_ap.patch -index 3487ab2..1f06994 100644 ---- a/package/mac80211/patches/411-ath5k_allow_adhoc_and_ap.patch -+++ b/package/mac80211/patches/411-ath5k_allow_adhoc_and_ap.patch -@@ -18,7 +18,7 @@ - goto end; - --- a/drivers/net/wireless/ath/ath5k/base.c - +++ b/drivers/net/wireless/ath/ath5k/base.c --@@ -1934,7 +1934,7 @@ ath5k_beacon_send(struct ath5k_hw *ah) -+@@ -1937,7 +1937,7 @@ ath5k_beacon_send(struct ath5k_hw *ah) - } - - if ((ah->opmode == NL80211_IFTYPE_AP && ah->num_ap_vifs + -@@ -27,7 +27,7 @@ - ah->opmode == NL80211_IFTYPE_MESH_POINT) { - u64 tsf = ath5k_hw_get_tsf64(ah); - u32 tsftu = TSF_TO_TU(tsf); --@@ -2020,7 +2020,7 @@ ath5k_beacon_update_timers(struct ath5k_ -+@@ -2023,7 +2023,7 @@ ath5k_beacon_update_timers(struct ath5k_ - - intval = ah->bintval & AR5K_BEACON_PERIOD; - if (ah->opmode == NL80211_IFTYPE_AP && ah->num_ap_vifs -@@ -36,7 +36,7 @@ - intval /= ATH_BCBUF; /* staggered multi-bss beacons */ - if (intval < 15) - ATH5K_WARN(ah, "intval %u is too low, min 15\n", --@@ -2487,6 +2487,7 @@ static const struct ieee80211_iface_limi -+@@ -2490,6 +2490,7 @@ static const struct ieee80211_iface_limi - BIT(NL80211_IFTYPE_MESH_POINT) | - #endif - BIT(NL80211_IFTYPE_AP) }, -diff --git a/package/mac80211/patches/431-add_platform_eeprom_support_to_ath5k.patch b/package/mac80211/patches/431-add_platform_eeprom_support_to_ath5k.patch -index a223b38..5cb4b51 100644 ---- a/package/mac80211/patches/431-add_platform_eeprom_support_to_ath5k.patch -+++ b/package/mac80211/patches/431-add_platform_eeprom_support_to_ath5k.patch -@@ -22,14 +22,14 @@ - u32 status, timeout; - - + struct ath5k_platform_data *pdata = NULL; --+ -++ - + if (ah->pdev) - + pdata = ah->pdev->dev.platform_data; - + - + if (pdata && pdata->eeprom_data && pdata->eeprom_data[61] == AR5K_EEPROM_MAGIC_VALUE) { --+ if (offset >= ATH5K_PLAT_EEP_MAX_WORDS) -++ if (offset >= ATH5K_PLAT_EEP_MAX_WORDS) - + return false; --+ -++ - + *data = pdata->eeprom_data[offset]; - + return true; - + } -diff --git a/package/mac80211/patches/500-ath9k_eeprom_debugfs.patch b/package/mac80211/patches/500-ath9k_eeprom_debugfs.patch -index 664cf45..65821fe 100644 ---- a/package/mac80211/patches/500-ath9k_eeprom_debugfs.patch -+++ b/package/mac80211/patches/500-ath9k_eeprom_debugfs.patch -@@ -1,6 +1,6 @@ - --- a/drivers/net/wireless/ath/ath9k/debug.c - +++ b/drivers/net/wireless/ath/ath9k/debug.c --@@ -1481,6 +1481,53 @@ void ath9k_deinit_debug(struct ath_softc -+@@ -1289,6 +1289,53 @@ void ath9k_deinit_debug(struct ath_softc - ath9k_spectral_deinit_debug(sc); - } - -@@ -54,7 +54,7 @@ - int ath9k_init_debug(struct ath_hw *ah) - { - struct ath_common *common = ath9k_hw_common(ah); --@@ -1500,6 +1547,8 @@ int ath9k_init_debug(struct ath_hw *ah) -+@@ -1308,6 +1355,8 @@ int ath9k_init_debug(struct ath_hw *ah) - ath9k_tx99_init_debug(sc); - ath9k_spectral_init_debug(sc); - -diff --git a/package/mac80211/patches/501-ath9k-eeprom_endianess.patch b/package/mac80211/patches/501-ath9k-eeprom_endianess.patch -index 96e7c6d..169eb9a 100644 ---- a/package/mac80211/patches/501-ath9k-eeprom_endianess.patch -+++ b/package/mac80211/patches/501-ath9k-eeprom_endianess.patch -@@ -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 --@@ -722,6 +722,8 @@ static int ath9k_init_softc(u16 devid, s -+@@ -518,6 +518,8 @@ static int ath9k_init_softc(u16 devid, s - ah->is_clk_25mhz = pdata->is_clk_25mhz; - ah->get_mac_revision = pdata->get_mac_revision; - ah->external_reset = pdata->external_reset; -diff --git a/package/mac80211/patches/502-ath9k_ahb_init.patch b/package/mac80211/patches/502-ath9k_ahb_init.patch -index 4edc63b..0c8e813 100644 ---- a/package/mac80211/patches/502-ath9k_ahb_init.patch -+++ b/package/mac80211/patches/502-ath9k_ahb_init.patch -@@ -1,15 +1,15 @@ - --- a/drivers/net/wireless/ath/ath9k/init.c - +++ b/drivers/net/wireless/ath/ath9k/init.c --@@ -1112,23 +1112,23 @@ static int __init ath9k_init(void) -- goto err_out; -- } -+@@ -904,23 +904,23 @@ static int __init ath9k_init(void) -+ { -+ int error; - - - error = ath_pci_init(); - + error = ath_ahb_init(); - if (error < 0) { - - pr_err("No PCI devices found, driver not installed\n"); - error = -ENODEV; -- goto err_rate_unregister; -+ goto err_out; - } - - - error = ath_ahb_init(); -@@ -27,6 +27,6 @@ - - ath_pci_exit(); - + err_ahb_exit: - + ath_ahb_exit(); -- -- err_rate_unregister: -- ath_rate_control_unregister(); -+ err_out: -+ return error; -+ } -diff --git a/package/mac80211/patches/511-ath9k_reduce_rxbuf.patch b/package/mac80211/patches/511-ath9k_reduce_rxbuf.patch -index ef0b9a1..e457267 100644 ---- a/package/mac80211/patches/511-ath9k_reduce_rxbuf.patch -+++ b/package/mac80211/patches/511-ath9k_reduce_rxbuf.patch -@@ -1,6 +1,6 @@ - --- a/drivers/net/wireless/ath/ath9k/ath9k.h - +++ b/drivers/net/wireless/ath/ath9k/ath9k.h --@@ -90,7 +90,7 @@ int ath_descdma_setup(struct ath_softc * -+@@ -89,7 +89,7 @@ int ath_descdma_setup(struct ath_softc * - (_l) &= ((_sz) - 1); \ - } while (0) - -diff --git a/package/mac80211/patches/512-ath9k_channelbw_debugfs.patch b/package/mac80211/patches/512-ath9k_channelbw_debugfs.patch -index 8f3cc03..c0e173f 100644 ---- a/package/mac80211/patches/512-ath9k_channelbw_debugfs.patch -+++ b/package/mac80211/patches/512-ath9k_channelbw_debugfs.patch -@@ -1,6 +1,6 @@ - --- a/drivers/net/wireless/ath/ath9k/debug.c - +++ b/drivers/net/wireless/ath/ath9k/debug.c --@@ -1528,6 +1528,52 @@ static const struct file_operations fops -+@@ -1336,6 +1336,52 @@ static const struct file_operations fops - .owner = THIS_MODULE - }; - -@@ -35,7 +35,7 @@ - + return -EINVAL; - + - + common->chan_bw = chan_bw; --+ if (!test_bit(SC_OP_INVALID, &sc->sc_flags)) -++ if (!test_bit(ATH_OP_INVALID, &common->op_flags)) - + ath9k_ops.config(sc->hw, IEEE80211_CONF_CHANGE_CHANNEL); - + - + return count; -@@ -53,7 +53,7 @@ - int ath9k_init_debug(struct ath_hw *ah) - { - struct ath_common *common = ath9k_hw_common(ah); --@@ -1549,6 +1595,8 @@ int ath9k_init_debug(struct ath_hw *ah) -+@@ -1357,6 +1403,8 @@ int ath9k_init_debug(struct ath_hw *ah) - - debugfs_create_file("eeprom", S_IRUSR, sc->debug.debugfs_phy, sc, - &fops_eeprom); -@@ -64,17 +64,17 @@ - debugfs_create_file("interrupt", S_IRUSR, sc->debug.debugfs_phy, sc, - --- a/drivers/net/wireless/ath/ath.h - +++ b/drivers/net/wireless/ath/ath.h --@@ -130,6 +130,7 @@ struct ath_common { -- struct ieee80211_hw *hw; -+@@ -140,6 +140,7 @@ struct ath_common { - int debug_mask; - enum ath_device_state state; -+ unsigned long op_flags; - + u32 chan_bw; - - struct ath_ani ani; - - --- a/drivers/net/wireless/ath/ath9k/common.c - +++ b/drivers/net/wireless/ath/ath9k/common.c --@@ -52,11 +52,13 @@ EXPORT_SYMBOL(ath9k_cmn_get_hw_crypto_ke -+@@ -296,11 +296,13 @@ EXPORT_SYMBOL(ath9k_cmn_get_hw_crypto_ke - /* - * Update internal channel flags. - */ -@@ -89,7 +89,7 @@ - - ichan->channel = chan->center_freq; - ichan->chan = chan; --@@ -64,7 +66,19 @@ static void ath9k_cmn_update_ichannel(st -+@@ -308,7 +310,19 @@ static void ath9k_cmn_update_ichannel(st - if (chan->band == IEEE80211_BAND_5GHZ) - flags |= CHANNEL_5GHZ; - -@@ -110,7 +110,7 @@ - case NL80211_CHAN_WIDTH_5: - flags |= CHANNEL_QUARTER; - break; --@@ -97,10 +111,11 @@ struct ath9k_channel *ath9k_cmn_get_chan -+@@ -341,10 +355,11 @@ struct ath9k_channel *ath9k_cmn_get_chan - struct cfg80211_chan_def *chandef) - { - struct ieee80211_channel *curchan = chandef->chan; -diff --git a/package/mac80211/patches/520-mac80211_cur_txpower.patch b/package/mac80211/patches/520-mac80211_cur_txpower.patch -index 6df95bc..ef7906e 100644 ---- a/package/mac80211/patches/520-mac80211_cur_txpower.patch -+++ b/package/mac80211/patches/520-mac80211_cur_txpower.patch -@@ -1,6 +1,6 @@ - --- a/include/net/mac80211.h - +++ b/include/net/mac80211.h --@@ -1711,6 +1711,7 @@ struct ieee80211_hw { -+@@ -1718,6 +1718,7 @@ struct ieee80211_hw { - u8 max_tx_aggregation_subframes; - u8 offchannel_tx_hw_queue; - u8 radiotap_mcs_details; -@@ -10,7 +10,7 @@ - u8 uapsd_queues; - --- a/net/mac80211/cfg.c - +++ b/net/mac80211/cfg.c --@@ -2329,7 +2329,9 @@ static int ieee80211_get_tx_power(struct -+@@ -2084,7 +2084,9 @@ static int ieee80211_get_tx_power(struct - struct ieee80211_local *local = wiphy_priv(wiphy); - struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev); - -@@ -23,7 +23,7 @@ - *dbm = sdata->vif.bss_conf.txpower; - --- a/net/mac80211/main.c - +++ b/net/mac80211/main.c --@@ -158,6 +158,7 @@ static u32 ieee80211_hw_conf_chan(struct -+@@ -156,6 +156,7 @@ static u32 ieee80211_hw_conf_chan(struct - - if (local->hw.conf.power_level != power) { - changed |= IEEE80211_CONF_CHANGE_POWER; -diff --git a/package/mac80211/patches/521-ath9k_cur_txpower.patch b/package/mac80211/patches/521-ath9k_cur_txpower.patch -index 0d6c360..83ff465 100644 ---- a/package/mac80211/patches/521-ath9k_cur_txpower.patch -+++ b/package/mac80211/patches/521-ath9k_cur_txpower.patch -@@ -1,6 +1,6 @@ - --- a/drivers/net/wireless/ath/ath9k/main.c - +++ b/drivers/net/wireless/ath/ath9k/main.c --@@ -308,8 +308,12 @@ static int ath_reset_internal(struct ath -+@@ -310,8 +310,12 @@ static int ath_reset_internal(struct ath - (sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)) - ath9k_mci_set_txpower(sc, true, false); - -@@ -14,7 +14,7 @@ - - out: - spin_unlock_bh(&sc->sc_pcu_lock); --@@ -1371,6 +1375,7 @@ static int ath9k_config(struct ieee80211 -+@@ -1405,6 +1409,7 @@ static int ath9k_config(struct ieee80211 - sc->config.txpowlimit = 2 * conf->power_level; - ath9k_cmn_update_txpow(ah, sc->curtxpow, - sc->config.txpowlimit, &sc->curtxpow); -diff --git a/package/mac80211/patches/522-mac80211_configure_antenna_gain.patch b/package/mac80211/patches/522-mac80211_configure_antenna_gain.patch -index 308ee6e..2109d2e 100644 ---- a/package/mac80211/patches/522-mac80211_configure_antenna_gain.patch -+++ b/package/mac80211/patches/522-mac80211_configure_antenna_gain.patch -@@ -1,6 +1,6 @@ - --- a/include/net/cfg80211.h - +++ b/include/net/cfg80211.h --@@ -2156,6 +2156,7 @@ struct cfg80211_qos_map { -+@@ -2207,6 +2207,7 @@ struct cfg80211_qos_map { - * (as advertised by the nl80211 feature flag.) - * @get_tx_power: store the current TX power into the dbm variable; - * return 0 if successful -@@ -8,7 +8,7 @@ - * - * @set_wds_peer: set the WDS peer for a WDS interface - * --@@ -2380,6 +2381,7 @@ struct cfg80211_ops { -+@@ -2431,6 +2432,7 @@ struct cfg80211_ops { - enum nl80211_tx_power_setting type, int mbm); - int (*get_tx_power)(struct wiphy *wiphy, struct wireless_dev *wdev, - int *dbm); -@@ -18,7 +18,7 @@ - const u8 *addr); - --- a/include/net/mac80211.h - +++ b/include/net/mac80211.h --@@ -1033,6 +1033,7 @@ enum ieee80211_smps_mode { -+@@ -1032,6 +1032,7 @@ enum ieee80211_smps_mode { - * - * @power_level: requested transmit power (in dBm), backward compatibility - * value only that is set to the minimum of all interfaces -@@ -26,7 +26,7 @@ - * - * @chandef: the channel definition to tune to - * @radar_enabled: whether radar detection is enabled --@@ -1054,6 +1055,7 @@ struct ieee80211_conf { -+@@ -1053,6 +1054,7 @@ struct ieee80211_conf { - u32 flags; - int power_level, dynamic_ps_timeout; - int max_sleep_period; -@@ -36,9 +36,9 @@ - u8 ps_dtim_period; - --- a/include/uapi/linux/nl80211.h - +++ b/include/uapi/linux/nl80211.h --@@ -1555,6 +1555,9 @@ enum nl80211_commands { -- * data is in the format defined for the payload of the QoS Map Set element -- * in IEEE Std 802.11-2012, 8.4.2.97. -+@@ -1591,6 +1591,9 @@ enum nl80211_commands { -+ * creation then the new interface will be owned by the netlink socket -+ * that created it and will be destroyed when the socket is closed - * - + * @NL80211_ATTR_WIPHY_ANTENNA_GAIN: Configured antenna gain. Used to reduce - + * transmit power to stay within regulatory limits. u32, dBi. -@@ -46,9 +46,9 @@ - * @NL80211_ATTR_MAX: highest attribute number currently defined - * @__NL80211_ATTR_AFTER_LAST: internal use - */ --@@ -1883,6 +1886,8 @@ enum nl80211_attrs { -- -- NL80211_ATTR_QOS_MAP, -+@@ -1931,6 +1934,8 @@ enum nl80211_attrs { -+ NL80211_ATTR_CSA_C_OFFSETS_TX, -+ NL80211_ATTR_MAX_CSA_COUNTERS, - - + NL80211_ATTR_WIPHY_ANTENNA_GAIN, - + -@@ -57,7 +57,7 @@ - __NL80211_ATTR_AFTER_LAST, - --- a/net/mac80211/cfg.c - +++ b/net/mac80211/cfg.c --@@ -2339,6 +2339,19 @@ static int ieee80211_get_tx_power(struct -+@@ -2094,6 +2094,19 @@ static int ieee80211_get_tx_power(struct - return 0; - } - -@@ -77,7 +77,7 @@ - static int ieee80211_set_wds_peer(struct wiphy *wiphy, struct net_device *dev, - const u8 *addr) - { --@@ -3924,6 +3937,7 @@ struct cfg80211_ops mac80211_config_ops -+@@ -3517,6 +3530,7 @@ const struct cfg80211_ops mac80211_confi - .set_wiphy_params = ieee80211_set_wiphy_params, - .set_tx_power = ieee80211_set_tx_power, - .get_tx_power = ieee80211_get_tx_power, -@@ -87,7 +87,7 @@ - CFG80211_TESTMODE_CMD(ieee80211_testmode_cmd) - --- a/net/mac80211/ieee80211_i.h - +++ b/net/mac80211/ieee80211_i.h --@@ -1221,6 +1221,7 @@ struct ieee80211_local { -+@@ -1243,6 +1243,7 @@ struct ieee80211_local { - int dynamic_ps_forced_timeout; - - int user_power_level; /* in dBm, for all interfaces */ -@@ -97,39 +97,29 @@ - - --- a/net/mac80211/main.c - +++ b/net/mac80211/main.c --@@ -101,7 +101,7 @@ static u32 ieee80211_hw_conf_chan(struct -+@@ -97,7 +97,7 @@ static u32 ieee80211_hw_conf_chan(struct - struct ieee80211_sub_if_data *sdata; - struct cfg80211_chan_def chandef = {}; - u32 changed = 0; - - int power; --+ int power, ant_gain, max_power; -++ int power, max_power; - u32 offchannel_flag; - - offchannel_flag = local->hw.conf.flags & IEEE80211_CONF_OFFCHANNEL; --@@ -156,8 +156,21 @@ static u32 ieee80211_hw_conf_chan(struct -+@@ -154,6 +154,12 @@ static u32 ieee80211_hw_conf_chan(struct - } - rcu_read_unlock(); - --- if (local->hw.conf.power_level != power) { - + max_power = chandef.chan->max_reg_power; --+ ant_gain = chandef.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; -++ max_power -= local->user_antenna_gain; - + power = min(power, max_power); - + } - + --+ if (local->hw.conf.power_level != power || --+ local->hw.conf.max_antenna_gain != ant_gain) { -+ if (local->hw.conf.power_level != power) { - 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; -- } --@@ -584,6 +597,7 @@ struct ieee80211_hw *ieee80211_alloc_hw( -+@@ -584,6 +590,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; -@@ -139,32 +129,30 @@ - local->user_power_level = IEEE80211_UNSET_POWER_LEVEL; - --- a/net/wireless/nl80211.c - +++ b/net/wireless/nl80211.c --@@ -384,6 +384,7 @@ static const struct nla_policy nl80211_p -- [NL80211_ATTR_VENDOR_DATA] = { .type = NLA_BINARY }, -- [NL80211_ATTR_QOS_MAP] = { .type = NLA_BINARY, -- .len = IEEE80211_QOS_MAP_LEN_MAX }, -+@@ -387,6 +387,7 @@ static const struct nla_policy nl80211_p -+ [NL80211_ATTR_TDLS_PEER_CAPABILITY] = { .type = NLA_U32 }, -+ [NL80211_ATTR_IFACE_SOCKET_OWNER] = { .type = NLA_FLAG }, -+ [NL80211_ATTR_CSA_C_OFFSETS_TX] = { .type = NLA_BINARY }, - + [NL80211_ATTR_WIPHY_ANTENNA_GAIN] = { .type = NLA_U32 }, - }; - - /* policy for the key attributes */ --@@ -2105,6 +2106,22 @@ static int nl80211_set_wiphy(struct sk_b -- goto bad_res; -+@@ -2162,6 +2163,20 @@ static int nl80211_set_wiphy(struct sk_b -+ return result; - } - - + if (info->attrs[NL80211_ATTR_WIPHY_ANTENNA_GAIN]) { - + int idx, dbi = 0; - + --+ if (!rdev->ops->set_antenna_gain) { --+ result = -EOPNOTSUPP; --+ goto bad_res; --+ } -++ if (!rdev->ops->set_antenna_gain) -++ return -EOPNOTSUPP; - + - + 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; -++ return result; - + } - + - if (info->attrs[NL80211_ATTR_WIPHY_ANTENNA_TX] && -diff --git a/package/mac80211/patches/523-ath9k_use_configured_antenna_gain.patch b/package/mac80211/patches/523-ath9k_use_configured_antenna_gain.patch -index 30aa9ee..0b28ab8 100644 ---- a/package/mac80211/patches/523-ath9k_use_configured_antenna_gain.patch -+++ b/package/mac80211/patches/523-ath9k_use_configured_antenna_gain.patch -@@ -1,6 +1,6 @@ - --- a/drivers/net/wireless/ath/ath.h - +++ b/drivers/net/wireless/ath/ath.h --@@ -74,6 +74,7 @@ struct ath_regulatory { -+@@ -83,6 +83,7 @@ struct ath_regulatory { - u16 max_power_level; - u16 current_rd; - int16_t power_limit; -@@ -21,7 +21,7 @@ - if (ant_gain > max_gain) - --- a/drivers/net/wireless/ath/ath9k/main.c - +++ b/drivers/net/wireless/ath/ath9k/main.c --@@ -1371,7 +1371,10 @@ static int ath9k_config(struct ieee80211 -+@@ -1405,7 +1405,10 @@ static int ath9k_config(struct ieee80211 - } - - if (changed & IEEE80211_CONF_CHANGE_POWER) { -diff --git a/package/mac80211/patches/530-ath9k_extra_leds.patch b/package/mac80211/patches/530-ath9k_extra_leds.patch -index 59f78d9..b5f2f8b 100644 ---- a/package/mac80211/patches/530-ath9k_extra_leds.patch -+++ b/package/mac80211/patches/530-ath9k_extra_leds.patch -@@ -1,6 +1,6 @@ - --- a/drivers/net/wireless/ath/ath9k/ath9k.h - +++ b/drivers/net/wireless/ath/ath9k/ath9k.h --@@ -563,6 +563,9 @@ static inline int ath9k_dump_btcoex(stru -+@@ -564,6 +564,9 @@ static inline int ath9k_dump_btcoex(stru - void ath_init_leds(struct ath_softc *sc); - void ath_deinit_leds(struct ath_softc *sc); - void ath_fill_led_pin(struct ath_softc *sc); -@@ -10,7 +10,7 @@ - #else - static inline void ath_init_leds(struct ath_softc *sc) - { --@@ -710,6 +713,13 @@ enum sc_op_flags { -+@@ -702,6 +705,13 @@ void ath_ant_comb_scan(struct ath_softc - #define PS_BEACON_SYNC BIT(4) - #define PS_WAIT_FOR_ANI BIT(5) - -@@ -24,8 +24,8 @@ - struct ath_softc { - struct ieee80211_hw *hw; - struct device *dev; --@@ -751,9 +761,8 @@ struct ath_softc { -- struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS]; -+@@ -744,9 +754,8 @@ struct ath_softc { -+ struct ath_beacon beacon; - - #ifdef CPTCFG_MAC80211_LEDS - - bool led_registered; -@@ -162,7 +162,7 @@ - void ath_fill_led_pin(struct ath_softc *sc) - --- a/drivers/net/wireless/ath/ath9k/init.c - +++ b/drivers/net/wireless/ath/ath9k/init.c --@@ -1018,7 +1018,7 @@ int ath9k_init_device(u16 devid, struct -+@@ -815,7 +815,7 @@ int ath9k_init_device(u16 devid, struct - - #ifdef CPTCFG_MAC80211_LEDS - /* must be initialized before ieee80211_register_hw */ -@@ -173,7 +173,7 @@ - #endif - --- a/drivers/net/wireless/ath/ath9k/debug.c - +++ b/drivers/net/wireless/ath/ath9k/debug.c --@@ -1573,6 +1573,61 @@ static const struct file_operations fops -+@@ -1381,6 +1381,61 @@ static const struct file_operations fops - .llseek = default_llseek, - }; - -@@ -235,7 +235,7 @@ - - int ath9k_init_debug(struct ath_hw *ah) - { --@@ -1597,6 +1652,10 @@ int ath9k_init_debug(struct ath_hw *ah) -+@@ -1405,6 +1460,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); -diff --git a/package/mac80211/patches/531-ath9k_extra_platform_leds.patch b/package/mac80211/patches/531-ath9k_extra_platform_leds.patch -index 6c9832c..718a3d0 100644 ---- a/package/mac80211/patches/531-ath9k_extra_platform_leds.patch -+++ b/package/mac80211/patches/531-ath9k_extra_platform_leds.patch -@@ -1,9 +1,9 @@ - --- a/include/linux/ath9k_platform.h - +++ b/include/linux/ath9k_platform.h --@@ -37,6 +37,9 @@ struct ath9k_platform_data { -- -- int (*get_mac_revision)(void); -+@@ -39,6 +39,9 @@ struct ath9k_platform_data { - int (*external_reset)(void); -+ -+ bool use_eeprom; - + - + int num_leds; - + const struct gpio_led *leds; -diff --git a/package/mac80211/patches/542-ath9k_debugfs_diag.patch b/package/mac80211/patches/542-ath9k_debugfs_diag.patch -index e1b6ff1..2a56352 100644 ---- a/package/mac80211/patches/542-ath9k_debugfs_diag.patch -+++ b/package/mac80211/patches/542-ath9k_debugfs_diag.patch -@@ -1,6 +1,6 @@ - --- a/drivers/net/wireless/ath/ath9k/debug.c - +++ b/drivers/net/wireless/ath/ath9k/debug.c --@@ -1629,6 +1629,50 @@ static const struct file_operations fops -+@@ -1437,6 +1437,50 @@ static const struct file_operations fops - #endif - - -@@ -51,7 +51,7 @@ - int ath9k_init_debug(struct ath_hw *ah) - { - struct ath_common *common = ath9k_hw_common(ah); --@@ -1656,6 +1700,8 @@ int ath9k_init_debug(struct ath_hw *ah) -+@@ -1464,6 +1508,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 -@@ -125,7 +125,7 @@ - REG_SET_BIT(ah, AR_BTCOEX_WL_LNADIV, AR_BTCOEX_WL_LNADIV_FORCE_ON); - --- a/drivers/net/wireless/ath/ath9k/main.c - +++ b/drivers/net/wireless/ath/ath9k/main.c --@@ -602,6 +602,11 @@ irqreturn_t ath_isr(int irq, void *dev) -+@@ -606,6 +606,11 @@ irqreturn_t ath_isr(int irq, void *dev) - ath9k_debug_sync_cause(sc, sync_cause); - status &= ah->imask; /* discard unasked-for bits */ - -diff --git a/package/mac80211/patches/543-ath9k-allow-to-disable-bands-via-platform-data.patch b/package/mac80211/patches/543-ath9k-allow-to-disable-bands-via-platform-data.patch -index d26a5af..0501582 100644 ---- a/package/mac80211/patches/543-ath9k-allow-to-disable-bands-via-platform-data.patch -+++ b/package/mac80211/patches/543-ath9k-allow-to-disable-bands-via-platform-data.patch -@@ -58,7 +58,7 @@ - }; - --- a/drivers/net/wireless/ath/ath9k/init.c - +++ b/drivers/net/wireless/ath/ath9k/init.c --@@ -722,6 +722,8 @@ static int ath9k_init_softc(u16 devid, s -+@@ -518,6 +518,8 @@ static int ath9k_init_softc(u16 devid, s - ah->is_clk_25mhz = pdata->is_clk_25mhz; - ah->get_mac_revision = pdata->get_mac_revision; - ah->external_reset = pdata->external_reset; -diff --git a/package/mac80211/patches/550-ath9k_entropy_from_adc.patch b/package/mac80211/patches/550-ath9k_entropy_from_adc.patch -index b59c362..7210a02 100644 ---- a/package/mac80211/patches/550-ath9k_entropy_from_adc.patch -+++ b/package/mac80211/patches/550-ath9k_entropy_from_adc.patch -@@ -55,7 +55,7 @@ - ops->spectral_scan_config = ar9003_hw_spectral_scan_config; - --- a/drivers/net/wireless/ath/ath9k/init.c - +++ b/drivers/net/wireless/ath/ath9k/init.c --@@ -846,7 +846,8 @@ static void ath9k_init_txpower_limits(st -+@@ -646,7 +646,8 @@ static void ath9k_init_txpower_limits(st - if (ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ) - ath9k_init_band_txpower(sc, IEEE80211_BAND_5GHZ); - -@@ -64,8 +64,8 @@ - + ah->curchan = curchan; - } - -- void ath9k_reload_chainmask_settings(struct ath_softc *sc) --@@ -980,6 +981,18 @@ static void ath9k_set_hw_capab(struct at -+ static const struct ieee80211_iface_limit if_limits[] = { -+@@ -774,6 +775,18 @@ static void ath9k_set_hw_capab(struct at - SET_IEEE80211_PERM_ADDR(hw, common->macaddr); - } - -@@ -84,7 +84,7 @@ - int ath9k_init_device(u16 devid, struct ath_softc *sc, - const struct ath_bus_ops *bus_ops) - { --@@ -1025,6 +1038,8 @@ int ath9k_init_device(u16 devid, struct -+@@ -822,6 +835,8 @@ int ath9k_init_device(u16 devid, struct - ARRAY_SIZE(ath9k_tpt_blink)); - #endif - -@@ -110,7 +110,7 @@ - static inline void ath9k_hw_set_bt_ant_diversity(struct ath_hw *ah, bool enable) - --- a/drivers/net/wireless/ath/ath9k/link.c - +++ b/drivers/net/wireless/ath/ath9k/link.c --@@ -307,6 +307,11 @@ void ath_ani_calibrate(unsigned long dat -+@@ -308,6 +308,11 @@ void ath_ani_calibrate(unsigned long dat - unsigned int timestamp = jiffies_to_msecs(jiffies); - u32 cal_interval, short_cal_interval, long_cal_interval; - unsigned long flags; -diff --git a/package/mac80211/patches/551-ath9k-ar933x-usb-hang-workaround.patch b/package/mac80211/patches/551-ath9k-ar933x-usb-hang-workaround.patch -new file mode 100644 -index 0000000..10280d9 ---- /dev/null -+++ b/package/mac80211/patches/551-ath9k-ar933x-usb-hang-workaround.patch -@@ -0,0 +1,79 @@ -+--- a/drivers/net/wireless/ath/ath9k/hw.c -++++ b/drivers/net/wireless/ath/ath9k/hw.c -+@@ -215,6 +215,19 @@ void ath9k_hw_get_channel_centers(struct -+ centers->synth_center + (extoff * HT40_CHANNEL_CENTER_SHIFT); -+ } -+ -++static inline void ath9k_hw_disable_pll_lock_detect(struct ath_hw *ah) -++{ -++ /* On AR9330 and AR9340 devices, some PHY registers must be -++ * tuned to gain better stability/performance. These registers -++ * might be changed while doing wlan reset so the registers must -++ * be reprogrammed after each reset. -++ */ -++ REG_CLR_BIT(ah, AR_PHY_USB_CTRL1, BIT(20)); -++ REG_RMW(ah, AR_PHY_USB_CTRL2, -++ (1 << 21) | (0xf << 22), -++ (1 << 21) | (0x3 << 22)); -++} -++ -+ /******************/ -+ /* Chip Revisions */ -+ /******************/ -+@@ -1337,6 +1350,9 @@ static bool ath9k_hw_set_reset(struct at -+ if (AR_SREV_9100(ah)) -+ udelay(50); -+ -++ if (AR_SREV_9330(ah) || AR_SREV_9340(ah)) -++ ath9k_hw_disable_pll_lock_detect(ah); -++ -+ return true; -+ } -+ -+@@ -1436,6 +1452,9 @@ static bool ath9k_hw_chip_reset(struct a -+ ar9003_hw_internal_regulator_apply(ah); -+ ath9k_hw_init_pll(ah, chan); -+ -++ if (AR_SREV_9330(ah) || AR_SREV_9340(ah)) -++ ath9k_hw_disable_pll_lock_detect(ah); -++ -+ return true; -+ } -+ -+@@ -1730,8 +1749,14 @@ static int ath9k_hw_do_fastcc(struct ath -+ if (AR_SREV_9271(ah)) -+ ar9002_hw_load_ani_reg(ah, chan); -+ -++ if (AR_SREV_9330(ah) || AR_SREV_9340(ah)) -++ ath9k_hw_disable_pll_lock_detect(ah); -++ -+ return 0; -+ fail: -++ if (AR_SREV_9330(ah) || AR_SREV_9340(ah)) -++ ath9k_hw_disable_pll_lock_detect(ah); -++ -+ return -EINVAL; -+ } -+ -+@@ -1959,6 +1984,9 @@ int ath9k_hw_reset(struct ath_hw *ah, st -+ if (AR_SREV_9565(ah) && common->bt_ant_diversity) -+ REG_SET_BIT(ah, AR_BTCOEX_WL_LNADIV, AR_BTCOEX_WL_LNADIV_FORCE_ON); -+ -++ if (AR_SREV_9330(ah) || AR_SREV_9340(ah)) -++ ath9k_hw_disable_pll_lock_detect(ah); -++ -+ return 0; -+ } -+ EXPORT_SYMBOL(ath9k_hw_reset); -+--- a/drivers/net/wireless/ath/ath9k/phy.h -++++ b/drivers/net/wireless/ath/ath9k/phy.h -+@@ -48,6 +48,9 @@ -+ #define AR_PHY_PLL_CONTROL 0x16180 -+ #define AR_PHY_PLL_MODE 0x16184 -+ -++#define AR_PHY_USB_CTRL1 0x16c84 -++#define AR_PHY_USB_CTRL2 0x16c88 -++ -+ enum ath9k_ant_div_comb_lna_conf { -+ ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2, -+ ATH_ANT_DIV_COMB_LNA2, -diff --git a/package/mac80211/patches/551-ath9k_p2p_ifcomb.patch b/package/mac80211/patches/551-ath9k_p2p_ifcomb.patch -deleted file mode 100644 -index ffffe0c..0000000 ---- a/package/mac80211/patches/551-ath9k_p2p_ifcomb.patch -+++ /dev/null -@@ -1,33 +0,0 @@ --From c997a1da25fe7c717ed099888b8eb35d4e139e70 Mon Sep 17 00:00:00 2001 --From: Felix Fietkau --Date: Sun, 8 Dec 2013 08:52:52 +0100 --Subject: [PATCH] ath9k: support only one P2P interface -- --Preparation for adding P2P powersave and multi-channel support. -- --Signed-off-by: Felix Fietkau ----- -- drivers/net/wireless/ath/ath9k/init.c | 4 ++-- -- 1 file changed, 2 insertions(+), 2 deletions(-) -- ----- a/drivers/net/wireless/ath/ath9k/init.c --+++ b/drivers/net/wireless/ath/ath9k/init.c --@@ -863,15 +863,15 @@ void ath9k_reload_chainmask_settings(str -- -- static const struct ieee80211_iface_limit if_limits[] = { -- { .max = 2048, .types = BIT(NL80211_IFTYPE_STATION) | --- BIT(NL80211_IFTYPE_P2P_CLIENT) | -- BIT(NL80211_IFTYPE_WDS) }, -- { .max = 8, .types = -- #ifdef CPTCFG_MAC80211_MESH -- BIT(NL80211_IFTYPE_MESH_POINT) | -- #endif --- BIT(NL80211_IFTYPE_AP) | --- BIT(NL80211_IFTYPE_P2P_GO) }, --+ BIT(NL80211_IFTYPE_AP) }, -- { .max = 1, .types = BIT(NL80211_IFTYPE_ADHOC) }, --+ { .max = 1, .types = BIT(NL80211_IFTYPE_P2P_CLIENT) | --+ BIT(NL80211_IFTYPE_P2P_GO) }, -- }; -- -- static const struct ieee80211_iface_limit if_dfs_limits[] = { -diff --git a/package/mac80211/patches/552-ath9k_p2p_ps_support.patch b/package/mac80211/patches/552-ath9k_p2p_ps_support.patch -deleted file mode 100644 -index 4a61db3..0000000 ---- a/package/mac80211/patches/552-ath9k_p2p_ps_support.patch -+++ /dev/null -@@ -1,247 +0,0 @@ --From 6744d0a7ea037c7d65e13ca906da93009b241d00 Mon Sep 17 00:00:00 2001 --From: Felix Fietkau --Date: Tue, 11 Feb 2014 11:16:24 +0100 --Subject: [PATCH] ath9k: implement p2p client powersave support -- --Use generic TSF timers to trigger powersave state changes based --information from the P2P NoA attribute. --Opportunistic Powersave is not handled, because the driver does not --support powersave at the moment. -- --Signed-off-by: Felix Fietkau ----- -- drivers/net/wireless/ath/ath9k/ath9k.h | 12 ++++ -- drivers/net/wireless/ath/ath9k/init.c | 6 ++ -- drivers/net/wireless/ath/ath9k/main.c | 104 +++++++++++++++++++++++++++++++++ -- drivers/net/wireless/ath/ath9k/recv.c | 3 + -- 4 files changed, 125 insertions(+) -- ----- a/drivers/net/wireless/ath/ath9k/main.c --+++ b/drivers/net/wireless/ath/ath9k/main.c --@@ -261,6 +261,8 @@ static bool ath_complete_reset(struct at -- sc->gtt_cnt = 0; -- ieee80211_wake_queues(sc->hw); -- --+ ath9k_p2p_ps_timer(sc); --+ -- return true; -- } -- --@@ -1126,6 +1128,8 @@ static int ath9k_add_interface(struct ie -- if (ath9k_uses_beacons(vif->type)) -- ath9k_beacon_assign_slot(sc, vif); -- --+ avp->vif = vif; --+ -- an->sc = sc; -- an->sta = NULL; -- an->vif = vif; --@@ -1170,6 +1174,29 @@ static int ath9k_change_interface(struct -- return 0; -- } -- --+static void --+ath9k_update_p2p_ps_timer(struct ath_softc *sc, struct ath_vif *avp) --+{ --+ struct ath_hw *ah = sc->sc_ah; --+ s32 tsf, target_tsf; --+ --+ if (!avp || !avp->noa.has_next_tsf) --+ return; --+ --+ ath9k_hw_gen_timer_stop(ah, sc->p2p_ps_timer); --+ --+ tsf = ath9k_hw_gettsf32(sc->sc_ah); --+ --+ target_tsf = avp->noa.next_tsf; --+ if (!avp->noa.absent) --+ target_tsf -= ATH_P2P_PS_STOP_TIME; --+ --+ if (target_tsf - tsf < ATH_P2P_PS_STOP_TIME) --+ target_tsf = tsf + ATH_P2P_PS_STOP_TIME; --+ --+ ath9k_hw_gen_timer_start(ah, sc->p2p_ps_timer, (u32) target_tsf, 1000000); --+} --+ -- static void ath9k_remove_interface(struct ieee80211_hw *hw, -- struct ieee80211_vif *vif) -- { --@@ -1181,6 +1208,13 @@ static void ath9k_remove_interface(struc -- -- mutex_lock(&sc->mutex); -- --+ spin_lock_bh(&sc->sc_pcu_lock); --+ if (avp == sc->p2p_ps_vif) { --+ sc->p2p_ps_vif = NULL; --+ ath9k_update_p2p_ps_timer(sc, NULL); --+ } --+ spin_unlock_bh(&sc->sc_pcu_lock); --+ -- sc->nvifs--; -- sc->tx99_vif = NULL; -- --@@ -1649,6 +1683,70 @@ static void ath9k_bss_assoc_iter(void *d -- ath9k_set_assoc_state(sc, vif); -- } -- --+void ath9k_p2p_ps_timer(void *priv) --+{ --+ struct ath_softc *sc = priv; --+ struct ath_vif *avp = sc->p2p_ps_vif; --+ struct ieee80211_vif *vif; --+ struct ieee80211_sta *sta; --+ struct ath_node *an; --+ u32 tsf; --+ --+ if (!avp) --+ return; --+ --+ tsf = ath9k_hw_gettsf32(sc->sc_ah); --+ if (!avp->noa.absent) --+ tsf += ATH_P2P_PS_STOP_TIME; --+ --+ if (!avp->noa.has_next_tsf || --+ avp->noa.next_tsf - tsf > BIT(31)) --+ ieee80211_update_p2p_noa(&avp->noa, tsf); --+ --+ ath9k_update_p2p_ps_timer(sc, avp); --+ --+ rcu_read_lock(); --+ --+ vif = avp->vif; --+ sta = ieee80211_find_sta(vif, vif->bss_conf.bssid); --+ if (!sta) --+ goto out; --+ --+ an = (void *) sta->drv_priv; --+ if (an->sleeping == !!avp->noa.absent) --+ goto out; --+ --+ an->sleeping = avp->noa.absent; --+ if (an->sleeping) --+ ath_tx_aggr_sleep(sta, sc, an); --+ else --+ ath_tx_aggr_wakeup(sc, an); --+ --+out: --+ rcu_read_unlock(); --+} --+ --+void ath9k_update_p2p_ps(struct ath_softc *sc, struct ieee80211_vif *vif) --+{ --+ struct ath_vif *avp = (void *)vif->drv_priv; --+ u32 tsf; --+ --+ if (!sc->p2p_ps_timer) --+ return; --+ --+ if (vif->type != NL80211_IFTYPE_STATION || !vif->p2p) --+ return; --+ --+ sc->p2p_ps_vif = avp; --+ --+ if (sc->ps_flags & PS_BEACON_SYNC) --+ return; --+ --+ tsf = ath9k_hw_gettsf32(sc->sc_ah); --+ ieee80211_parse_p2p_noa(&vif->bss_conf.p2p_noa_attr, &avp->noa, tsf); --+ ath9k_update_p2p_ps_timer(sc, avp); --+} --+ -- static void ath9k_bss_info_changed(struct ieee80211_hw *hw, -- struct ieee80211_vif *vif, -- struct ieee80211_bss_conf *bss_conf, --@@ -1723,6 +1821,12 @@ static void ath9k_bss_info_changed(struc -- } -- } -- --+ if (changed & BSS_CHANGED_P2P_PS) { --+ spin_lock_bh(&sc->sc_pcu_lock); --+ ath9k_update_p2p_ps(sc, vif); --+ spin_unlock_bh(&sc->sc_pcu_lock); --+ } --+ -- if (changed & CHECK_ANI) -- ath_check_ani(sc); -- ----- a/drivers/net/wireless/ath/ath9k/ath9k.h --+++ b/drivers/net/wireless/ath/ath9k/ath9k.h --@@ -115,6 +115,9 @@ int ath_descdma_setup(struct ath_softc * -- #define ATH_TXFIFO_DEPTH 8 -- #define ATH_TX_ERROR 0x01 -- --+/* Stop tx traffic 1ms before the GO goes away */ --+#define ATH_P2P_PS_STOP_TIME 1000 --+ -- #define IEEE80211_SEQ_SEQ_SHIFT 4 -- #define IEEE80211_SEQ_MAX 4096 -- #define IEEE80211_WEP_IVLEN 3 --@@ -363,11 +366,15 @@ void ath9k_release_buffered_frames(struc -- /********/ -- -- struct ath_vif { --+ struct ieee80211_vif *vif; -- struct ath_node mcast_node; -- int av_bslot; -- bool primary_sta_vif; -- __le64 tsf_adjust; /* TSF adjustment for staggered beacons */ -- struct ath_buf *av_bcbuf; --+ --+ /* P2P Client */ --+ struct ieee80211_noa_data noa; -- }; -- -- struct ath9k_vif_iter_data { --@@ -472,6 +479,8 @@ int ath_update_survey_stats(struct ath_s -- void ath_update_survey_nf(struct ath_softc *sc, int channel); -- void ath9k_queue_reset(struct ath_softc *sc, enum ath_reset_type type); -- void ath_ps_full_sleep(unsigned long data); --+void ath9k_p2p_ps_timer(void *priv); --+void ath9k_update_p2p_ps(struct ath_softc *sc, struct ieee80211_vif *vif); -- -- /**********/ -- /* BTCOEX */ --@@ -741,6 +750,9 @@ struct ath_softc { -- struct completion paprd_complete; -- wait_queue_head_t tx_wait; -- --+ struct ath_gen_timer *p2p_ps_timer; --+ struct ath_vif *p2p_ps_vif; --+ -- unsigned long sc_flags; -- unsigned long driver_data; -- ----- a/drivers/net/wireless/ath/ath9k/init.c --+++ b/drivers/net/wireless/ath/ath9k/init.c --@@ -797,6 +797,9 @@ static int ath9k_init_softc(u16 devid, s -- if (ret) -- goto err_btcoex; -- --+ sc->p2p_ps_timer = ath_gen_timer_alloc(sc->sc_ah, ath9k_p2p_ps_timer, --+ NULL, sc, AR_FIRST_NDP_TIMER); --+ -- ath9k_cmn_init_crypto(sc->sc_ah); -- ath9k_init_misc(sc); -- ath_fill_led_pin(sc); --@@ -1082,6 +1085,9 @@ static void ath9k_deinit_softc(struct at -- { -- int i = 0; -- --+ if (sc->p2p_ps_timer) --+ ath_gen_timer_free(sc->sc_ah, sc->p2p_ps_timer); --+ -- ath9k_deinit_btcoex(sc); -- -- for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) ----- a/drivers/net/wireless/ath/ath9k/recv.c --+++ b/drivers/net/wireless/ath/ath9k/recv.c --@@ -539,6 +539,9 @@ static void ath_rx_ps_beacon(struct ath_ -- ath_dbg(common, PS, -- "Reconfigure beacon timers based on synchronized timestamp\n"); -- ath9k_set_beacon(sc); --+ --+ if (sc->p2p_ps_vif) --+ ath9k_update_p2p_ps(sc, sc->p2p_ps_vif->vif); -- } -- -- if (ath_beacon_dtim_pending_cab(skb)) { -diff --git a/package/mac80211/patches/560-ath9k_pcoem_optional.patch b/package/mac80211/patches/560-ath9k_pcoem_optional.patch -new file mode 100644 -index 0000000..4d4ea3b ---- /dev/null -+++ b/package/mac80211/patches/560-ath9k_pcoem_optional.patch -@@ -0,0 +1,249 @@ -+--- a/drivers/net/wireless/ath/ath9k/Kconfig -++++ b/drivers/net/wireless/ath/ath9k/Kconfig -+@@ -133,6 +133,11 @@ config ATH9K_RFKILL -+ seconds. Turn off to save power, but enable it if you have -+ a platform that can toggle the RF-Kill GPIO. -+ -++config ATH9K_PCOEM -++ bool "Atheros ath9k support for PC OEM cards" if EXPERT -++ depends on ATH9K -++ default y -++ -+ config ATH9K_HTC -+ tristate "Atheros HTC based wireless cards support" -+ depends on m -+--- a/drivers/net/wireless/ath/ath9k/Makefile -++++ b/drivers/net/wireless/ath/ath9k/Makefile -+@@ -31,7 +31,6 @@ ath9k_hw-y:= \ -+ ar5008_phy.o \ -+ ar9002_calib.o \ -+ ar9003_calib.o \ -+- ar9003_rtt.o \ -+ calib.o \ -+ eeprom.o \ -+ eeprom_def.o \ -+@@ -48,6 +47,8 @@ ath9k_hw-$(CPTCFG_ATH9K_WOW) += ar9003_w -+ -+ ath9k_hw-$(CPTCFG_ATH9K_BTCOEX_SUPPORT) += btcoex.o \ -+ ar9003_mci.o -++ath9k_hw-$(CPTCFG_ATH9K_PCOEM) += ar9003_rtt.o -++ -+ obj-$(CPTCFG_ATH9K_HW) += ath9k_hw.o -+ -+ obj-$(CPTCFG_ATH9K_COMMON) += ath9k_common.o -+--- a/drivers/net/wireless/ath/ath9k/ar9003_rtt.h -++++ b/drivers/net/wireless/ath/ath9k/ar9003_rtt.h -+@@ -17,6 +17,7 @@ -+ #ifndef AR9003_RTT_H -+ #define AR9003_RTT_H -+ -++#ifdef CPTCFG_ATH9K_PCOEM -+ void ar9003_hw_rtt_enable(struct ath_hw *ah); -+ void ar9003_hw_rtt_disable(struct ath_hw *ah); -+ void ar9003_hw_rtt_set_mask(struct ath_hw *ah, u32 rtt_mask); -+@@ -25,5 +26,40 @@ void ar9003_hw_rtt_load_hist(struct ath_ -+ void ar9003_hw_rtt_fill_hist(struct ath_hw *ah); -+ void ar9003_hw_rtt_clear_hist(struct ath_hw *ah); -+ bool ar9003_hw_rtt_restore(struct ath_hw *ah, struct ath9k_channel *chan); -++#else -++static inline void ar9003_hw_rtt_enable(struct ath_hw *ah) -++{ -++} -++ -++static inline void ar9003_hw_rtt_disable(struct ath_hw *ah) -++{ -++} -++ -++static inline void ar9003_hw_rtt_set_mask(struct ath_hw *ah, u32 rtt_mask) -++{ -++} -++ -++static inline bool ar9003_hw_rtt_force_restore(struct ath_hw *ah) -++{ -++ return false; -++} -++ -++static inline void ar9003_hw_rtt_load_hist(struct ath_hw *ah) -++{ -++} -++ -++static inline void ar9003_hw_rtt_fill_hist(struct ath_hw *ah) -++{ -++} -++ -++static inline void ar9003_hw_rtt_clear_hist(struct ath_hw *ah) -++{ -++} -++ -++static inline bool ar9003_hw_rtt_restore(struct ath_hw *ah, struct ath9k_channel *chan) -++{ -++ return false; -++} -++#endif -+ -+ #endif -+--- a/drivers/net/wireless/ath/ath9k/hw.h -++++ b/drivers/net/wireless/ath/ath9k/hw.h -+@@ -244,13 +244,20 @@ enum ath9k_hw_caps { -+ ATH9K_HW_CAP_2GHZ = BIT(11), -+ ATH9K_HW_CAP_5GHZ = BIT(12), -+ ATH9K_HW_CAP_APM = BIT(13), -++#ifdef CPTCFG_ATH9K_PCOEM -+ ATH9K_HW_CAP_RTT = BIT(14), -+ ATH9K_HW_CAP_MCI = BIT(15), -+- ATH9K_HW_CAP_DFS = BIT(16), -+- ATH9K_HW_WOW_DEVICE_CAPABLE = BIT(17), -+- ATH9K_HW_CAP_PAPRD = BIT(18), -+- ATH9K_HW_CAP_FCC_BAND_SWITCH = BIT(19), -+- ATH9K_HW_CAP_BT_ANT_DIV = BIT(20), -++ ATH9K_HW_WOW_DEVICE_CAPABLE = BIT(16), -++ ATH9K_HW_CAP_BT_ANT_DIV = BIT(17), -++#else -++ ATH9K_HW_CAP_RTT = 0, -++ ATH9K_HW_CAP_MCI = 0, -++ ATH9K_HW_WOW_DEVICE_CAPABLE = 0, -++ ATH9K_HW_CAP_BT_ANT_DIV = 0, -++#endif -++ ATH9K_HW_CAP_DFS = BIT(18), -++ ATH9K_HW_CAP_PAPRD = BIT(19), -++ ATH9K_HW_CAP_FCC_BAND_SWITCH = BIT(20), -+ }; -+ -+ /* -+--- a/drivers/net/wireless/ath/ath9k/init.c -++++ b/drivers/net/wireless/ath/ath9k/init.c -+@@ -355,6 +355,9 @@ static void ath9k_init_pcoem_platform(st -+ struct ath9k_hw_capabilities *pCap = &ah->caps; -+ struct ath_common *common = ath9k_hw_common(ah); -+ -++ if (!IS_ENABLED(CPTCFG_ATH9K_PCOEM)) -++ return; -++ -+ if (common->bus_ops->ath_bus_type != ATH_PCI) -+ return; -+ -+--- a/drivers/net/wireless/ath/ath9k/pci.c -++++ b/drivers/net/wireless/ath/ath9k/pci.c -+@@ -30,6 +30,7 @@ static DEFINE_PCI_DEVICE_TABLE(ath_pci_i -+ { PCI_VDEVICE(ATHEROS, 0x0029) }, /* PCI */ -+ { PCI_VDEVICE(ATHEROS, 0x002A) }, /* PCI-E */ -+ -++#ifdef CPTCFG_ATH9K_PCOEM -+ { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, -+ 0x002A, -+ PCI_VENDOR_ID_AZWAVE, -+@@ -82,6 +83,7 @@ static DEFINE_PCI_DEVICE_TABLE(ath_pci_i -+ PCI_VENDOR_ID_AZWAVE, -+ 0x2C37), -+ .driver_data = ATH9K_PCI_BT_ANT_DIV }, -++#endif -+ -+ { PCI_VDEVICE(ATHEROS, 0x002B) }, /* PCI-E */ -+ { PCI_VDEVICE(ATHEROS, 0x002C) }, /* PCI-E 802.11n bonded out */ -+@@ -102,6 +104,7 @@ static DEFINE_PCI_DEVICE_TABLE(ath_pci_i -+ -+ { PCI_VDEVICE(ATHEROS, 0x0030) }, /* PCI-E AR9300 */ -+ -++#ifdef CPTCFG_ATH9K_PCOEM -+ /* PCI-E CUS198 */ -+ { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, -+ 0x0032, -+@@ -294,10 +297,12 @@ static DEFINE_PCI_DEVICE_TABLE(ath_pci_i -+ PCI_VENDOR_ID_ASUSTEK, -+ 0x850D), -+ .driver_data = ATH9K_PCI_NO_PLL_PWRSAVE }, -++#endif -+ -+ { PCI_VDEVICE(ATHEROS, 0x0032) }, /* PCI-E AR9485 */ -+ { PCI_VDEVICE(ATHEROS, 0x0033) }, /* PCI-E AR9580 */ -+ -++#ifdef CPTCFG_ATH9K_PCOEM -+ /* PCI-E CUS217 */ -+ { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, -+ 0x0034, -+@@ -657,6 +662,7 @@ static DEFINE_PCI_DEVICE_TABLE(ath_pci_i -+ /* PCI-E AR9565 (WB335) */ -+ { PCI_VDEVICE(ATHEROS, 0x0036), -+ .driver_data = ATH9K_PCI_BT_ANT_DIV }, -++#endif -+ -+ { PCI_VDEVICE(ATHEROS, 0xabcd) }, /* PCI-E internal chip default ID */ -+ { 0 } -+--- a/drivers/net/wireless/ath/ath9k/reg.h -++++ b/drivers/net/wireless/ath/ath9k/reg.h -+@@ -891,10 +891,21 @@ -+ (AR_SREV_9330((_ah)) && \ -+ ((_ah)->hw_version.macRev == AR_SREV_REVISION_9330_12)) -+ -++#ifdef CPTCFG_ATH9K_PCOEM -++#define AR_SREV_9462(_ah) \ -++ (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9462)) -+ #define AR_SREV_9485(_ah) \ -+ (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9485)) -++#define AR_SREV_9565(_ah) \ -++ (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9565)) -++#else -++#define AR_SREV_9462(_ah) 0 -++#define AR_SREV_9485(_ah) 0 -++#define AR_SREV_9565(_ah) 0 -++#endif -++ -+ #define AR_SREV_9485_11_OR_LATER(_ah) \ -+- (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9485) && \ -++ (AR_SREV_9485(_ah) && \ -+ ((_ah)->hw_version.macRev >= AR_SREV_REVISION_9485_11)) -+ #define AR_SREV_9485_OR_LATER(_ah) \ -+ (((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9485)) -+@@ -910,34 +921,30 @@ -+ (AR_SREV_9285_12_OR_LATER(_ah) && \ -+ ((REG_READ(_ah, AR_AN_SYNTH9) & 0x7) == 0x1)) -+ -+-#define AR_SREV_9462(_ah) \ -+- (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9462)) -+ #define AR_SREV_9462_20(_ah) \ -+- (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9462) && \ -++ (AR_SREV_9462(_ah) && \ -+ ((_ah)->hw_version.macRev == AR_SREV_REVISION_9462_20)) -+ #define AR_SREV_9462_21(_ah) \ -+- (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9462) && \ -++ (AR_SREV_9462(_ah) && \ -+ ((_ah)->hw_version.macRev == AR_SREV_REVISION_9462_21)) -+ #define AR_SREV_9462_20_OR_LATER(_ah) \ -+- (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9462) && \ -++ (AR_SREV_9462(_ah) && \ -+ ((_ah)->hw_version.macRev >= AR_SREV_REVISION_9462_20)) -+ #define AR_SREV_9462_21_OR_LATER(_ah) \ -+- (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9462) && \ -++ (AR_SREV_9462(_ah) && \ -+ ((_ah)->hw_version.macRev >= AR_SREV_REVISION_9462_21)) -+ -+-#define AR_SREV_9565(_ah) \ -+- (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9565)) -+ #define AR_SREV_9565_10(_ah) \ -+- (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9565) && \ -++ (AR_SREV_9565(_ah) && \ -+ ((_ah)->hw_version.macRev == AR_SREV_REVISION_9565_10)) -+ #define AR_SREV_9565_101(_ah) \ -+- (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9565) && \ -++ (AR_SREV_9565(_ah) && \ -+ ((_ah)->hw_version.macRev == AR_SREV_REVISION_9565_101)) -+ #define AR_SREV_9565_11(_ah) \ -+- (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9565) && \ -++ (AR_SREV_9565(_ah) && \ -+ ((_ah)->hw_version.macRev == AR_SREV_REVISION_9565_11)) -+ #define AR_SREV_9565_11_OR_LATER(_ah) \ -+- (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9565) && \ -++ (AR_SREV_9565(_ah) && \ -+ ((_ah)->hw_version.macRev >= AR_SREV_REVISION_9565_11)) -+ -+ #define AR_SREV_9550(_ah) \ -+--- a/.local-symbols -++++ b/.local-symbols -+@@ -129,6 +129,7 @@ ATH9K_HW= -+ ATH9K_COMMON= -+ ATH9K_DFS_DEBUGFS= -+ ATH9K_BTCOEX_SUPPORT= -++ATH9K_PCOEM= -+ ATH9K= -+ ATH9K_PCI= -+ ATH9K_AHB= -diff --git a/package/mac80211/patches/561-ath9k_remove_gain_tables.patch b/package/mac80211/patches/561-ath9k_remove_gain_tables.patch -new file mode 100644 -index 0000000..852eae3 ---- /dev/null -+++ b/package/mac80211/patches/561-ath9k_remove_gain_tables.patch -@@ -0,0 +1,12 @@ -+--- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c -++++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c -+@@ -663,9 +663,6 @@ static void ar9003_tx_gain_table_mode5(s -+ if (AR_SREV_9485_11_OR_LATER(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); -diff --git a/package/mac80211/patches/562-ath9k_ani_ws_detect.patch b/package/mac80211/patches/562-ath9k_ani_ws_detect.patch -new file mode 100644 -index 0000000..1e4f451 ---- /dev/null -+++ b/package/mac80211/patches/562-ath9k_ani_ws_detect.patch -@@ -0,0 +1,155 @@ -+--- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c -++++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c -+@@ -929,55 +929,6 @@ static bool ar5008_hw_ani_control_new(st -+ * on == 0 means more noise imm -+ */ -+ u32 on = param ? 1 : 0; -+- /* -+- * make register setting for default -+- * (weak sig detect ON) come from INI file -+- */ -+- int m1ThreshLow = on ? -+- aniState->iniDef.m1ThreshLow : m1ThreshLow_off; -+- int m2ThreshLow = on ? -+- aniState->iniDef.m2ThreshLow : m2ThreshLow_off; -+- int m1Thresh = on ? -+- aniState->iniDef.m1Thresh : m1Thresh_off; -+- int m2Thresh = on ? -+- aniState->iniDef.m2Thresh : m2Thresh_off; -+- int m2CountThr = on ? -+- aniState->iniDef.m2CountThr : m2CountThr_off; -+- int m2CountThrLow = on ? -+- aniState->iniDef.m2CountThrLow : m2CountThrLow_off; -+- int m1ThreshLowExt = on ? -+- aniState->iniDef.m1ThreshLowExt : m1ThreshLowExt_off; -+- int m2ThreshLowExt = on ? -+- aniState->iniDef.m2ThreshLowExt : m2ThreshLowExt_off; -+- int m1ThreshExt = on ? -+- aniState->iniDef.m1ThreshExt : m1ThreshExt_off; -+- int m2ThreshExt = on ? -+- aniState->iniDef.m2ThreshExt : m2ThreshExt_off; -+- -+- REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW, -+- AR_PHY_SFCORR_LOW_M1_THRESH_LOW, -+- m1ThreshLow); -+- REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW, -+- AR_PHY_SFCORR_LOW_M2_THRESH_LOW, -+- m2ThreshLow); -+- REG_RMW_FIELD(ah, AR_PHY_SFCORR, -+- AR_PHY_SFCORR_M1_THRESH, m1Thresh); -+- REG_RMW_FIELD(ah, AR_PHY_SFCORR, -+- AR_PHY_SFCORR_M2_THRESH, m2Thresh); -+- REG_RMW_FIELD(ah, AR_PHY_SFCORR, -+- AR_PHY_SFCORR_M2COUNT_THR, m2CountThr); -+- REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW, -+- AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW, -+- m2CountThrLow); -+- -+- REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT, -+- AR_PHY_SFCORR_EXT_M1_THRESH_LOW, m1ThreshLowExt); -+- REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT, -+- AR_PHY_SFCORR_EXT_M2_THRESH_LOW, m2ThreshLowExt); -+- REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT, -+- AR_PHY_SFCORR_EXT_M1_THRESH, m1ThreshExt); -+- REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT, -+- AR_PHY_SFCORR_EXT_M2_THRESH, m2ThreshExt); -+ -+ if (on) -+ REG_SET_BIT(ah, AR_PHY_SFCORR_LOW, -+--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c -++++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c -+@@ -26,20 +26,6 @@ static const int cycpwrThr1_table[] = -+ /* level: 0 1 2 3 4 5 6 7 8 */ -+ { -6, -4, -2, 0, 2, 4, 6, 8 }; /* lvl 0-7, default 3 */ -+ -+-/* -+- * register values to turn OFDM weak signal detection OFF -+- */ -+-static const int m1ThreshLow_off = 127; -+-static const int m2ThreshLow_off = 127; -+-static const int m1Thresh_off = 127; -+-static const int m2Thresh_off = 127; -+-static const int m2CountThr_off = 31; -+-static const int m2CountThrLow_off = 63; -+-static const int m1ThreshLowExt_off = 127; -+-static const int m2ThreshLowExt_off = 127; -+-static const int m1ThreshExt_off = 127; -+-static const int m2ThreshExt_off = 127; -+- -+ /** -+ * ar9003_hw_set_channel - set channel on single-chip device -+ * @ah: atheros hardware structure -+@@ -954,11 +940,6 @@ static bool ar9003_hw_ani_control(struct -+ struct ath_common *common = ath9k_hw_common(ah); -+ struct ath9k_channel *chan = ah->curchan; -+ struct ar5416AniState *aniState = &ah->ani; -+- int m1ThreshLow, m2ThreshLow; -+- int m1Thresh, m2Thresh; -+- int m2CountThr, m2CountThrLow; -+- int m1ThreshLowExt, m2ThreshLowExt; -+- int m1ThreshExt, m2ThreshExt; -+ s32 value, value2; -+ -+ switch (cmd & ah->ani_function) { -+@@ -972,61 +953,6 @@ static bool ar9003_hw_ani_control(struct -+ */ -+ u32 on = param ? 1 : 0; -+ -+- if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) -+- goto skip_ws_det; -+- -+- m1ThreshLow = on ? -+- aniState->iniDef.m1ThreshLow : m1ThreshLow_off; -+- m2ThreshLow = on ? -+- aniState->iniDef.m2ThreshLow : m2ThreshLow_off; -+- m1Thresh = on ? -+- aniState->iniDef.m1Thresh : m1Thresh_off; -+- m2Thresh = on ? -+- aniState->iniDef.m2Thresh : m2Thresh_off; -+- m2CountThr = on ? -+- aniState->iniDef.m2CountThr : m2CountThr_off; -+- m2CountThrLow = on ? -+- aniState->iniDef.m2CountThrLow : m2CountThrLow_off; -+- m1ThreshLowExt = on ? -+- aniState->iniDef.m1ThreshLowExt : m1ThreshLowExt_off; -+- m2ThreshLowExt = on ? -+- aniState->iniDef.m2ThreshLowExt : m2ThreshLowExt_off; -+- m1ThreshExt = on ? -+- aniState->iniDef.m1ThreshExt : m1ThreshExt_off; -+- m2ThreshExt = on ? -+- aniState->iniDef.m2ThreshExt : m2ThreshExt_off; -+- -+- REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW, -+- AR_PHY_SFCORR_LOW_M1_THRESH_LOW, -+- m1ThreshLow); -+- REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW, -+- AR_PHY_SFCORR_LOW_M2_THRESH_LOW, -+- m2ThreshLow); -+- REG_RMW_FIELD(ah, AR_PHY_SFCORR, -+- AR_PHY_SFCORR_M1_THRESH, -+- m1Thresh); -+- REG_RMW_FIELD(ah, AR_PHY_SFCORR, -+- AR_PHY_SFCORR_M2_THRESH, -+- m2Thresh); -+- REG_RMW_FIELD(ah, AR_PHY_SFCORR, -+- AR_PHY_SFCORR_M2COUNT_THR, -+- m2CountThr); -+- REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW, -+- AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW, -+- m2CountThrLow); -+- REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT, -+- AR_PHY_SFCORR_EXT_M1_THRESH_LOW, -+- m1ThreshLowExt); -+- REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT, -+- AR_PHY_SFCORR_EXT_M2_THRESH_LOW, -+- m2ThreshLowExt); -+- REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT, -+- AR_PHY_SFCORR_EXT_M1_THRESH, -+- m1ThreshExt); -+- REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT, -+- AR_PHY_SFCORR_EXT_M2_THRESH, -+- m2ThreshExt); -+-skip_ws_det: -+ if (on) -+ REG_SET_BIT(ah, AR_PHY_SFCORR_LOW, -+ AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW); -diff --git a/package/mac80211/patches/563-ath9k_rxorn_intr_fix.patch b/package/mac80211/patches/563-ath9k_rxorn_intr_fix.patch -new file mode 100644 -index 0000000..47a7d82 ---- /dev/null -+++ b/package/mac80211/patches/563-ath9k_rxorn_intr_fix.patch -@@ -0,0 +1,12 @@ -+--- a/drivers/net/wireless/ath/ath9k/main.c -++++ b/drivers/net/wireless/ath/ath9k/main.c -+@@ -628,8 +628,7 @@ irqreturn_t ath_isr(int irq, void *dev) -+ * If a FATAL or RXORN interrupt is received, we have to reset the -+ * chip immediately. -+ */ -+- if ((status & ATH9K_INT_FATAL) || ((status & ATH9K_INT_RXORN) && -+- !(ah->caps.hw_caps & ATH9K_HW_CAP_EDMA))) -++ if (status & ATH9K_INT_FATAL) -+ goto chip_reset; -+ -+ if ((ah->config.hw_hang_checks & HW_BB_WATCHDOG) && -diff --git a/package/mac80211/patches/564-ath9k_cleanup_reset_debug.patch b/package/mac80211/patches/564-ath9k_cleanup_reset_debug.patch -new file mode 100644 -index 0000000..c636c5a ---- /dev/null -+++ b/package/mac80211/patches/564-ath9k_cleanup_reset_debug.patch -@@ -0,0 +1,60 @@ -+--- a/drivers/net/wireless/ath/ath9k/debug.c -++++ b/drivers/net/wireless/ath/ath9k/debug.c -+@@ -846,36 +846,30 @@ static ssize_t read_file_reset(struct fi -+ size_t count, loff_t *ppos) -+ { -+ struct ath_softc *sc = file->private_data; -++ static const char * const reset_cause[__RESET_TYPE_MAX] = { -++ [RESET_TYPE_BB_HANG] = "Baseband Hang", -++ [RESET_TYPE_BB_WATCHDOG] = "Baseband Watchdog", -++ [RESET_TYPE_FATAL_INT] = "Fatal HW Error", -++ [RESET_TYPE_TX_ERROR] = "TX HW error", -++ [RESET_TYPE_TX_GTT] = "Transmit timeout", -++ [RESET_TYPE_TX_HANG] = "TX Path Hang", -++ [RESET_TYPE_PLL_HANG] = "PLL RX Hang", -++ [RESET_TYPE_MAC_HANG] = "MAC Hang", -++ [RESET_TYPE_BEACON_STUCK] = "Stuck Beacon", -++ [RESET_TYPE_MCI] = "MCI Reset", -++ }; -+ char buf[512]; -+ unsigned int len = 0; -++ int i; -+ -+- len += scnprintf(buf + len, sizeof(buf) - len, -+- "%17s: %2d\n", "Baseband Hang", -+- sc->debug.stats.reset[RESET_TYPE_BB_HANG]); -+- len += scnprintf(buf + len, sizeof(buf) - len, -+- "%17s: %2d\n", "Baseband Watchdog", -+- sc->debug.stats.reset[RESET_TYPE_BB_WATCHDOG]); -+- len += scnprintf(buf + len, sizeof(buf) - len, -+- "%17s: %2d\n", "Fatal HW Error", -+- sc->debug.stats.reset[RESET_TYPE_FATAL_INT]); -+- len += scnprintf(buf + len, sizeof(buf) - len, -+- "%17s: %2d\n", "TX HW error", -+- sc->debug.stats.reset[RESET_TYPE_TX_ERROR]); -+- len += scnprintf(buf + len, sizeof(buf) - len, -+- "%17s: %2d\n", "TX Path Hang", -+- sc->debug.stats.reset[RESET_TYPE_TX_HANG]); -+- len += scnprintf(buf + len, sizeof(buf) - len, -+- "%17s: %2d\n", "PLL RX Hang", -+- sc->debug.stats.reset[RESET_TYPE_PLL_HANG]); -+- len += scnprintf(buf + len, sizeof(buf) - len, -+- "%17s: %2d\n", "MAC Hang", -+- sc->debug.stats.reset[RESET_TYPE_MAC_HANG]); -+- len += scnprintf(buf + len, sizeof(buf) - len, -+- "%17s: %2d\n", "Stuck Beacon", -+- sc->debug.stats.reset[RESET_TYPE_BEACON_STUCK]); -+- len += scnprintf(buf + len, sizeof(buf) - len, -+- "%17s: %2d\n", "MCI Reset", -+- sc->debug.stats.reset[RESET_TYPE_MCI]); -++ for (i = 0; i < ARRAY_SIZE(reset_cause); i++) { -++ if (!reset_cause[i]) -++ continue; -++ -++ len += scnprintf(buf + len, sizeof(buf) - len, -++ "%17s: %2d\n", reset_cause[i], -++ sc->debug.stats.reset[i]); -++ } -+ -+ if (len > sizeof(buf)) -+ len = sizeof(buf); -diff --git a/package/mac80211/patches/565-ath9k_restart_after_nfcal_failure.patch b/package/mac80211/patches/565-ath9k_restart_after_nfcal_failure.patch -new file mode 100644 -index 0000000..366cc3c ---- /dev/null -+++ b/package/mac80211/patches/565-ath9k_restart_after_nfcal_failure.patch -@@ -0,0 +1,172 @@ -+--- a/drivers/net/wireless/ath/ath9k/calib.c -++++ b/drivers/net/wireless/ath/ath9k/calib.c -+@@ -234,7 +234,7 @@ void ath9k_hw_start_nfcal(struct ath_hw -+ REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF); -+ } -+ -+-void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan) -++int ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan) -+ { -+ struct ath9k_nfcal_hist *h = NULL; -+ unsigned i, j; -+@@ -301,7 +301,7 @@ void ath9k_hw_loadnf(struct ath_hw *ah, -+ ath_dbg(common, ANY, -+ "Timeout while waiting for nf to load: AR_PHY_AGC_CONTROL=0x%x\n", -+ REG_READ(ah, AR_PHY_AGC_CONTROL)); -+- return; -++ return -ETIMEDOUT; -+ } -+ -+ /* -+@@ -322,6 +322,8 @@ void ath9k_hw_loadnf(struct ath_hw *ah, -+ } -+ } -+ REGWRITE_BUFFER_FLUSH(ah); -++ -++ return 0; -+ } -+ -+ -+--- a/drivers/net/wireless/ath/ath9k/calib.h -++++ b/drivers/net/wireless/ath/ath9k/calib.h -+@@ -109,7 +109,7 @@ struct ath9k_pacal_info{ -+ -+ bool ath9k_hw_reset_calvalid(struct ath_hw *ah); -+ void ath9k_hw_start_nfcal(struct ath_hw *ah, bool update); -+-void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan); -++int ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan); -+ bool ath9k_hw_getnf(struct ath_hw *ah, struct ath9k_channel *chan); -+ void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah, -+ struct ath9k_channel *chan); -+--- a/drivers/net/wireless/ath/ath9k/ar9002_calib.c -++++ b/drivers/net/wireless/ath/ath9k/ar9002_calib.c -+@@ -657,14 +657,13 @@ static void ar9002_hw_olc_temp_compensat -+ ar9280_hw_olc_temp_compensation(ah); -+ } -+ -+-static bool ar9002_hw_calibrate(struct ath_hw *ah, -+- struct ath9k_channel *chan, -+- u8 rxchainmask, -+- bool longcal) -++static int ar9002_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan, -++ u8 rxchainmask, bool longcal) -+ { -+ bool iscaldone = true; -+ struct ath9k_cal_list *currCal = ah->cal_list_curr; -+ bool nfcal, nfcal_pending = false; -++ int ret; -+ -+ nfcal = !!(REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF); -+ if (ah->caldata) -+@@ -698,7 +697,9 @@ static bool ar9002_hw_calibrate(struct a -+ * NF is slow time-variant, so it is OK to use a -+ * historical value. -+ */ -+- ath9k_hw_loadnf(ah, ah->curchan); -++ ret = ath9k_hw_loadnf(ah, ah->curchan); -++ if (ret < 0) -++ return ret; -+ } -+ -+ if (longcal) { -+--- a/drivers/net/wireless/ath/ath9k/hw-ops.h -++++ b/drivers/net/wireless/ath/ath9k/hw-ops.h -+@@ -41,10 +41,9 @@ static inline void ath9k_hw_set_desc_lin -+ ath9k_hw_ops(ah)->set_desc_link(ds, link); -+ } -+ -+-static inline bool ath9k_hw_calibrate(struct ath_hw *ah, -+- struct ath9k_channel *chan, -+- u8 rxchainmask, -+- bool longcal) -++static inline int ath9k_hw_calibrate(struct ath_hw *ah, -++ struct ath9k_channel *chan, -++ u8 rxchainmask, bool longcal) -+ { -+ return ath9k_hw_ops(ah)->calibrate(ah, chan, rxchainmask, longcal); -+ } -+--- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c -++++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c -+@@ -121,13 +121,12 @@ static bool ar9003_hw_per_calibration(st -+ return iscaldone; -+ } -+ -+-static bool ar9003_hw_calibrate(struct ath_hw *ah, -+- struct ath9k_channel *chan, -+- u8 rxchainmask, -+- bool longcal) -++static int ar9003_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan, -++ u8 rxchainmask, bool longcal) -+ { -+ bool iscaldone = true; -+ struct ath9k_cal_list *currCal = ah->cal_list_curr; -++ int ret; -+ -+ /* -+ * For given calibration: -+@@ -163,7 +162,9 @@ static bool ar9003_hw_calibrate(struct a -+ * NF is slow time-variant, so it is OK to use a historical -+ * value. -+ */ -+- ath9k_hw_loadnf(ah, ah->curchan); -++ ret = ath9k_hw_loadnf(ah, ah->curchan); -++ if (ret < 0) -++ return ret; -+ -+ /* start NF calibration, without updating BB NF register */ -+ ath9k_hw_start_nfcal(ah, false); -+--- a/drivers/net/wireless/ath/ath9k/hw.h -++++ b/drivers/net/wireless/ath/ath9k/hw.h -+@@ -695,10 +695,8 @@ struct ath_hw_ops { -+ bool power_off); -+ void (*rx_enable)(struct ath_hw *ah); -+ void (*set_desc_link)(void *ds, u32 link); -+- bool (*calibrate)(struct ath_hw *ah, -+- struct ath9k_channel *chan, -+- u8 rxchainmask, -+- bool longcal); -++ int (*calibrate)(struct ath_hw *ah, struct ath9k_channel *chan, -++ u8 rxchainmask, bool longcal); -+ bool (*get_isr)(struct ath_hw *ah, enum ath9k_int *masked, -+ u32 *sync_cause_p); -+ void (*set_txdesc)(struct ath_hw *ah, void *ds, -+--- a/drivers/net/wireless/ath/ath9k/debug.h -++++ b/drivers/net/wireless/ath/ath9k/debug.h -+@@ -49,6 +49,7 @@ enum ath_reset_type { -+ RESET_TYPE_MAC_HANG, -+ RESET_TYPE_BEACON_STUCK, -+ RESET_TYPE_MCI, -++ RESET_TYPE_CALIBRATION, -+ __RESET_TYPE_MAX -+ }; -+ -+--- a/drivers/net/wireless/ath/ath9k/debug.c -++++ b/drivers/net/wireless/ath/ath9k/debug.c -+@@ -857,6 +857,7 @@ static ssize_t read_file_reset(struct fi -+ [RESET_TYPE_MAC_HANG] = "MAC Hang", -+ [RESET_TYPE_BEACON_STUCK] = "Stuck Beacon", -+ [RESET_TYPE_MCI] = "MCI Reset", -++ [RESET_TYPE_CALIBRATION] = "Calibration error", -+ }; -+ char buf[512]; -+ unsigned int len = 0; -+--- a/drivers/net/wireless/ath/ath9k/link.c -++++ b/drivers/net/wireless/ath/ath9k/link.c -+@@ -376,9 +376,14 @@ void ath_ani_calibrate(unsigned long dat -+ -+ /* Perform calibration if necessary */ -+ if (longcal || shortcal) { -+- common->ani.caldone = -+- ath9k_hw_calibrate(ah, ah->curchan, -+- ah->rxchainmask, longcal); -++ int ret = ath9k_hw_calibrate(ah, ah->curchan, ah->rxchainmask, -++ longcal); -++ if (ret < 0) { -++ ath9k_queue_reset(sc, RESET_TYPE_CALIBRATION); -++ return; -++ } -++ -++ common->ani.caldone = ret; -+ } -+ -+ ath_dbg(common, ANI, -diff --git a/package/mac80211/patches/566-ath9k-ar933x-usb-hang-workaround.patch b/package/mac80211/patches/566-ath9k-ar933x-usb-hang-workaround.patch -deleted file mode 100644 -index af94c9e..0000000 ---- a/package/mac80211/patches/566-ath9k-ar933x-usb-hang-workaround.patch -+++ /dev/null -@@ -1,79 +0,0 @@ ----- a/drivers/net/wireless/ath/ath9k/hw.c --+++ b/drivers/net/wireless/ath/ath9k/hw.c --@@ -217,6 +217,19 @@ void ath9k_hw_get_channel_centers(struct -- centers->synth_center + (extoff * HT40_CHANNEL_CENTER_SHIFT); -- } -- --+static inline void ath9k_hw_disable_pll_lock_detect(struct ath_hw *ah) --+{ --+ /* On AR9330 and AR9340 devices, some PHY registers must be --+ * tuned to gain better stability/performance. These registers --+ * might be changed while doing wlan reset so the registers must --+ * be reprogrammed after each reset. --+ */ --+ REG_CLR_BIT(ah, AR_PHY_USB_CTRL1, BIT(20)); --+ REG_RMW(ah, AR_PHY_USB_CTRL2, --+ (1 << 21) | (0xf << 22), --+ (1 << 21) | (0x3 << 22)); --+} --+ -- /******************/ -- /* Chip Revisions */ -- /******************/ --@@ -1337,6 +1350,9 @@ static bool ath9k_hw_set_reset(struct at -- if (AR_SREV_9100(ah)) -- udelay(50); -- --+ if (AR_SREV_9330(ah) || AR_SREV_9340(ah)) --+ ath9k_hw_disable_pll_lock_detect(ah); --+ -- return true; -- } -- --@@ -1436,6 +1452,9 @@ static bool ath9k_hw_chip_reset(struct a -- ar9003_hw_internal_regulator_apply(ah); -- ath9k_hw_init_pll(ah, chan); -- --+ if (AR_SREV_9330(ah) || AR_SREV_9340(ah)) --+ ath9k_hw_disable_pll_lock_detect(ah); --+ -- return true; -- } -- --@@ -1730,8 +1749,14 @@ static int ath9k_hw_do_fastcc(struct ath -- if (AR_SREV_9271(ah)) -- ar9002_hw_load_ani_reg(ah, chan); -- --+ if (AR_SREV_9330(ah) || AR_SREV_9340(ah)) --+ ath9k_hw_disable_pll_lock_detect(ah); --+ -- return 0; -- fail: --+ if (AR_SREV_9330(ah) || AR_SREV_9340(ah)) --+ ath9k_hw_disable_pll_lock_detect(ah); --+ -- return -EINVAL; -- } -- --@@ -1959,6 +1984,9 @@ int ath9k_hw_reset(struct ath_hw *ah, st -- if (AR_SREV_9565(ah) && common->bt_ant_diversity) -- REG_SET_BIT(ah, AR_BTCOEX_WL_LNADIV, AR_BTCOEX_WL_LNADIV_FORCE_ON); -- --+ if (AR_SREV_9330(ah) || AR_SREV_9340(ah)) --+ ath9k_hw_disable_pll_lock_detect(ah); --+ -- return 0; -- } -- EXPORT_SYMBOL(ath9k_hw_reset); ----- a/drivers/net/wireless/ath/ath9k/phy.h --+++ b/drivers/net/wireless/ath/ath9k/phy.h --@@ -48,6 +48,9 @@ -- #define AR_PHY_PLL_CONTROL 0x16180 -- #define AR_PHY_PLL_MODE 0x16184 -- --+#define AR_PHY_USB_CTRL1 0x16c84 --+#define AR_PHY_USB_CTRL2 0x16c88 --+ -- enum ath9k_ant_div_comb_lna_conf { -- ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2, -- ATH_ANT_DIV_COMB_LNA2, -diff --git a/package/mac80211/patches/600-0001-rt2x00-rt2800lib-move-rt2800_drv_data-declaration-in.patch b/package/mac80211/patches/600-0001-rt2x00-rt2800lib-move-rt2800_drv_data-declaration-in.patch -new file mode 100644 -index 0000000..d344957 ---- /dev/null -+++ b/package/mac80211/patches/600-0001-rt2x00-rt2800lib-move-rt2800_drv_data-declaration-in.patch -@@ -0,0 +1,62 @@ -+From 7a69da907de668fb22a30ae218062d6f081864ea Mon Sep 17 00:00:00 2001 -+From: Gabor Juhos -+Date: Sat, 17 Aug 2013 19:31:41 +0200 -+Subject: [PATCH] rt2x00: rt2800lib: move rt2800_drv_data declaration into -+ rt2800lib.h -+ -+The rt2800_drv_data structure contains driver specific -+information. Move the declaration into the rt2800lib.h -+header which is a more logical place for it. Also fix -+the comment style to avoid checkpatch warning. -+ -+The patch contains no functional changes, it is in -+preparation for the next patch. -+ -+Signed-off-by: Gabor Juhos -+--- -+Changes since v1: --- -+--- -+ drivers/net/wireless/rt2x00/rt2800.h | 13 ------------- -+ drivers/net/wireless/rt2x00/rt2800lib.h | 11 +++++++++++ -+ 2 files changed, 11 insertions(+), 13 deletions(-) -+ -+--- a/drivers/net/wireless/rt2x00/rt2800.h -++++ b/drivers/net/wireless/rt2x00/rt2800.h -+@@ -2958,17 +2958,4 @@ enum rt2800_eeprom_word { -+ */ -+ #define BCN_TBTT_OFFSET 64 -+ -+-/* -+- * RT2800 driver data structure -+- */ -+-struct rt2800_drv_data { -+- u8 calibration_bw20; -+- u8 calibration_bw40; -+- u8 bbp25; -+- u8 bbp26; -+- u8 txmixer_gain_24g; -+- u8 txmixer_gain_5g; -+- unsigned int tbtt_tick; -+-}; -+- -+ #endif /* RT2800_H */ -+--- a/drivers/net/wireless/rt2x00/rt2800lib.h -++++ b/drivers/net/wireless/rt2x00/rt2800lib.h -+@@ -20,6 +20,17 @@ -+ #ifndef RT2800LIB_H -+ #define RT2800LIB_H -+ -++/* RT2800 driver data structure */ -++struct rt2800_drv_data { -++ u8 calibration_bw20; -++ u8 calibration_bw40; -++ u8 bbp25; -++ u8 bbp26; -++ u8 txmixer_gain_24g; -++ u8 txmixer_gain_5g; -++ unsigned int tbtt_tick; -++}; -++ -+ struct rt2800_ops { -+ void (*register_read)(struct rt2x00_dev *rt2x00dev, -+ const unsigned int offset, u32 *value); -diff --git a/package/mac80211/patches/600-0002-rt2x00-rt2800lib-introduce-RT2800_HAS_HIGH_SHARED_ME.patch b/package/mac80211/patches/600-0002-rt2x00-rt2800lib-introduce-RT2800_HAS_HIGH_SHARED_ME.patch -new file mode 100644 -index 0000000..60d4c55 ---- /dev/null -+++ b/package/mac80211/patches/600-0002-rt2x00-rt2800lib-introduce-RT2800_HAS_HIGH_SHARED_ME.patch -@@ -0,0 +1,80 @@ -+From a7f268af31dddf763fe3dbe9cbf96ea77e0540e0 Mon Sep 17 00:00:00 2001 -+From: Gabor Juhos -+Date: Sat, 17 Aug 2013 19:31:41 +0200 -+Subject: [PATCH] rt2x00: rt2800lib: introduce RT2800_HAS_HIGH_SHARED_MEM flag -+ -+Some chipsets have more than 16KB of shared memory. -+Introduce a new rt2800 specific flag to indicate that -+and add a helper function which helps to check the -+presence of the new flag. -+ -+Also enable the new flag for the RT3593 chipset which -+has 24KB of shared memory. The flag can also be used -+for other chipsets, but none of those has been tested -+yet. -+ -+Signed-off-by: Gabor Juhos -+--- -+Changes since v1: -+ - don't enable the new flag for RT3071 and RT5592 -+--- -+ drivers/net/wireless/rt2x00/rt2800lib.c | 4 ++++ -+ drivers/net/wireless/rt2x00/rt2800lib.h | 13 +++++++++++++ -+ 2 files changed, 17 insertions(+) -+ -+--- a/drivers/net/wireless/rt2x00/rt2800lib.c -++++ b/drivers/net/wireless/rt2x00/rt2800lib.c -+@@ -7734,6 +7734,7 @@ static int rt2800_probe_rt(struct rt2x00 -+ -+ int rt2800_probe_hw(struct rt2x00_dev *rt2x00dev) -+ { -++ struct rt2800_drv_data *drv_data = rt2x00dev->drv_data; -+ int retval; -+ u32 reg; -+ -+@@ -7741,6 +7742,9 @@ int rt2800_probe_hw(struct rt2x00_dev *r -+ if (retval) -+ return retval; -+ -++ if (rt2x00_rt(rt2x00dev, RT3593)) -++ __set_bit(RT2800_HAS_HIGH_SHARED_MEM, &drv_data->rt2800_flags); -++ -+ /* -+ * Allocate eeprom data. -+ */ -+--- a/drivers/net/wireless/rt2x00/rt2800lib.h -++++ b/drivers/net/wireless/rt2x00/rt2800lib.h -+@@ -20,6 +20,10 @@ -+ #ifndef RT2800LIB_H -+ #define RT2800LIB_H -+ -++enum rt2800_flag { -++ RT2800_HAS_HIGH_SHARED_MEM, -++}; -++ -+ /* RT2800 driver data structure */ -+ struct rt2800_drv_data { -+ u8 calibration_bw20; -+@@ -29,6 +33,8 @@ struct rt2800_drv_data { -+ u8 txmixer_gain_24g; -+ u8 txmixer_gain_5g; -+ unsigned int tbtt_tick; -++ -++ unsigned long rt2800_flags; -+ }; -+ -+ struct rt2800_ops { -+@@ -61,6 +67,13 @@ struct rt2800_ops { -+ __le32 *(*drv_get_txwi)(struct queue_entry *entry); -+ }; -+ -++static inline bool rt2800_has_high_shared_mem(struct rt2x00_dev *rt2x00dev) -++{ -++ struct rt2800_drv_data *drv_data = rt2x00dev->drv_data; -++ -++ return test_bit(RT2800_HAS_HIGH_SHARED_MEM, &drv_data->rt2800_flags); -++} -++ -+ static inline void rt2800_register_read(struct rt2x00_dev *rt2x00dev, -+ const unsigned int offset, -+ u32 *value) -diff --git a/package/mac80211/patches/600-0003-rt2x00-rt2800-serialize-shared-memory-access.patch b/package/mac80211/patches/600-0003-rt2x00-rt2800-serialize-shared-memory-access.patch -new file mode 100644 -index 0000000..2accf73 ---- /dev/null -+++ b/package/mac80211/patches/600-0003-rt2x00-rt2800-serialize-shared-memory-access.patch -@@ -0,0 +1,531 @@ -+From 250a1b520cd7fdc0df4fc3fedea9066913f49ecf Mon Sep 17 00:00:00 2001 -+From: Gabor Juhos -+Date: Sat, 17 Aug 2013 19:31:42 +0200 -+Subject: [PATCH] rt2x00: rt2800: serialize shared memory access -+ -+The shared memory of the rt2800 devices is accessible -+through the register offset range between 0x4000 and -+0x8000. The size of this range is 16KB only and on -+devices which have more than 16KB of shared memory either -+the low or the high part of the memory is accessible at a -+time. -+ -+Serialize all accesses to the shared memory by a mutex, -+in order to avoid concurrent use of that. -+ -+Signed-off-by: Gabor Juhos -+--- -+Changes since v1: --- -+--- -+ drivers/net/wireless/rt2x00/rt2800lib.c | 55 +++++++++++++++++++++++++++++- -+ drivers/net/wireless/rt2x00/rt2800lib.h | 32 +++++++++++++++++ -+ drivers/net/wireless/rt2x00/rt2800mmio.c | 26 ++++++++++++++ -+ drivers/net/wireless/rt2x00/rt2800mmio.h | 4 +++ -+ drivers/net/wireless/rt2x00/rt2800pci.c | 14 ++++++++ -+ drivers/net/wireless/rt2x00/rt2800soc.c | 3 ++ -+ drivers/net/wireless/rt2x00/rt2800usb.c | 31 +++++++++++++++++ -+ 7 files changed, 164 insertions(+), 1 deletion(-) -+ -+--- a/drivers/net/wireless/rt2x00/rt2800lib.c -++++ b/drivers/net/wireless/rt2x00/rt2800lib.c -+@@ -451,11 +451,13 @@ void rt2800_mcu_request(struct rt2x00_de -+ rt2x00_set_field32(®, H2M_MAILBOX_CSR_CMD_TOKEN, token); -+ rt2x00_set_field32(®, H2M_MAILBOX_CSR_ARG0, arg0); -+ rt2x00_set_field32(®, H2M_MAILBOX_CSR_ARG1, arg1); -++ rt2800_shared_mem_lock(rt2x00dev); -+ rt2800_register_write_lock(rt2x00dev, H2M_MAILBOX_CSR, reg); -+ -+ reg = 0; -+ rt2x00_set_field32(®, HOST_CMD_CSR_HOST_COMMAND, command); -+ rt2800_register_write_lock(rt2x00dev, HOST_CMD_CSR, reg); -++ rt2800_shared_mem_unlock(rt2x00dev); -+ } -+ -+ mutex_unlock(&rt2x00dev->csr_mutex); -+@@ -674,7 +676,9 @@ int rt2800_load_firmware(struct rt2x00_d -+ * Wait for device to stabilize. -+ */ -+ for (i = 0; i < REGISTER_BUSY_COUNT; i++) { -++ rt2800_shared_mem_lock(rt2x00dev); -+ rt2800_register_read(rt2x00dev, PBF_SYS_CTRL, ®); -++ rt2800_shared_mem_unlock(rt2x00dev); -+ if (rt2x00_get_field32(reg, PBF_SYS_CTRL_READY)) -+ break; -+ msleep(1); -+@@ -694,10 +698,16 @@ int rt2800_load_firmware(struct rt2x00_d -+ /* -+ * Initialize firmware. -+ */ -++ rt2800_shared_mem_lock(rt2x00dev); -+ rt2800_register_write(rt2x00dev, H2M_BBP_AGENT, 0); -+ rt2800_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0); -++ rt2800_shared_mem_unlock(rt2x00dev); -++ -+ if (rt2x00_is_usb(rt2x00dev)) { -++ rt2800_shared_mem_lock(rt2x00dev); -+ rt2800_register_write(rt2x00dev, H2M_INT_SRC, 0); -++ rt2800_shared_mem_unlock(rt2x00dev); -++ -+ rt2800_mcu_request(rt2x00dev, MCU_BOOT_SIGNAL, 0, 0, 0); -+ } -+ msleep(1); -+@@ -1035,8 +1045,10 @@ void rt2800_write_beacon(struct queue_en -+ -+ beacon_base = rt2800_hw_beacon_base(rt2x00dev, entry->entry_idx); -+ -++ rt2800_shared_mem_lock(rt2x00dev); -+ rt2800_register_multiwrite(rt2x00dev, beacon_base, entry->skb->data, -+ entry->skb->len + padding_len); -++ rt2800_shared_mem_unlock(rt2x00dev); -+ __set_bit(ENTRY_BCN_ENABLED, &entry->flags); -+ -+ /* -+@@ -1066,6 +1078,8 @@ static inline void rt2800_clear_beacon_r -+ -+ beacon_base = rt2800_hw_beacon_base(rt2x00dev, index); -+ -++ rt2800_shared_mem_lock(rt2x00dev); -++ -+ /* -+ * For the Beacon base registers we only need to clear -+ * the whole TXWI which (when set to 0) will invalidate -+@@ -1073,6 +1087,8 @@ static inline void rt2800_clear_beacon_r -+ */ -+ for (i = 0; i < txwi_desc_size; i += sizeof(__le32)) -+ rt2800_register_write(rt2x00dev, beacon_base + i, 0); -++ -++ rt2800_shared_mem_unlock(rt2x00dev); -+ } -+ -+ void rt2800_clear_beacon(struct queue_entry *entry) -+@@ -1261,7 +1277,9 @@ static void rt2800_delete_wcid_attr(stru -+ { -+ u32 offset; -+ offset = MAC_WCID_ATTR_ENTRY(wcid); -++ rt2800_shared_mem_lock(rt2x00dev); -+ rt2800_register_write(rt2x00dev, offset, 0); -++ rt2800_shared_mem_unlock(rt2x00dev); -+ } -+ -+ static void rt2800_config_wcid_attr_bssidx(struct rt2x00_dev *rt2x00dev, -+@@ -1274,11 +1292,13 @@ static void rt2800_config_wcid_attr_bssi -+ * The BSS Idx numbers is split in a main value of 3 bits, -+ * and a extended field for adding one additional bit to the value. -+ */ -++ rt2800_shared_mem_lock(rt2x00dev); -+ rt2800_register_read(rt2x00dev, offset, ®); -+ rt2x00_set_field32(®, MAC_WCID_ATTRIBUTE_BSS_IDX, (bssidx & 0x7)); -+ rt2x00_set_field32(®, MAC_WCID_ATTRIBUTE_BSS_IDX_EXT, -+ (bssidx & 0x8) >> 3); -+ rt2800_register_write(rt2x00dev, offset, reg); -++ rt2800_shared_mem_unlock(rt2x00dev); -+ } -+ -+ static void rt2800_config_wcid_attr_cipher(struct rt2x00_dev *rt2x00dev, -+@@ -1291,6 +1311,7 @@ static void rt2800_config_wcid_attr_ciph -+ -+ offset = MAC_WCID_ATTR_ENTRY(key->hw_key_idx); -+ -++ rt2800_shared_mem_lock(rt2x00dev); -+ if (crypto->cmd == SET_KEY) { -+ rt2800_register_read(rt2x00dev, offset, ®); -+ rt2x00_set_field32(®, MAC_WCID_ATTRIBUTE_KEYTAB, -+@@ -1315,6 +1336,7 @@ static void rt2800_config_wcid_attr_ciph -+ rt2x00_set_field32(®, MAC_WCID_ATTRIBUTE_RX_WIUDF, 0); -+ rt2800_register_write(rt2x00dev, offset, reg); -+ } -++ rt2800_shared_mem_unlock(rt2x00dev); -+ -+ offset = MAC_IVEIV_ENTRY(key->hw_key_idx); -+ -+@@ -1324,8 +1346,11 @@ static void rt2800_config_wcid_attr_ciph -+ (crypto->cipher == CIPHER_AES)) -+ iveiv_entry.iv[3] |= 0x20; -+ iveiv_entry.iv[3] |= key->keyidx << 6; -++ -++ rt2800_shared_mem_lock(rt2x00dev); -+ rt2800_register_multiwrite(rt2x00dev, offset, -+ &iveiv_entry, sizeof(iveiv_entry)); -++ rt2800_shared_mem_unlock(rt2x00dev); -+ } -+ -+ int rt2800_config_shared_key(struct rt2x00_dev *rt2x00dev, -+@@ -1348,8 +1373,11 @@ int rt2800_config_shared_key(struct rt2x -+ sizeof(key_entry.rx_mic)); -+ -+ offset = SHARED_KEY_ENTRY(key->hw_key_idx); -++ -++ rt2800_shared_mem_lock(rt2x00dev); -+ rt2800_register_multiwrite(rt2x00dev, offset, -+ &key_entry, sizeof(key_entry)); -++ rt2800_shared_mem_unlock(rt2x00dev); -+ } -+ -+ /* -+@@ -1364,10 +1392,12 @@ int rt2800_config_shared_key(struct rt2x -+ -+ offset = SHARED_KEY_MODE_ENTRY(key->hw_key_idx / 8); -+ -++ rt2800_shared_mem_lock(rt2x00dev); -+ rt2800_register_read(rt2x00dev, offset, ®); -+ rt2x00_set_field32(®, field, -+ (crypto->cmd == SET_KEY) * crypto->cipher); -+ rt2800_register_write(rt2x00dev, offset, reg); -++ rt2800_shared_mem_unlock(rt2x00dev); -+ -+ /* -+ * Update WCID information -+@@ -1437,8 +1467,11 @@ int rt2800_config_pairwise_key(struct rt -+ sizeof(key_entry.rx_mic)); -+ -+ offset = PAIRWISE_KEY_ENTRY(key->hw_key_idx); -++ -++ rt2800_shared_mem_lock(rt2x00dev); -+ rt2800_register_multiwrite(rt2x00dev, offset, -+ &key_entry, sizeof(key_entry)); -++ rt2800_shared_mem_unlock(rt2x00dev); -+ } -+ -+ /* -+@@ -4898,14 +4931,19 @@ static int rt2800_init_registers(struct -+ /* -+ * ASIC will keep garbage value after boot, clear encryption keys. -+ */ -++ rt2800_shared_mem_lock(rt2x00dev); -+ for (i = 0; i < 4; i++) -+ rt2800_register_write(rt2x00dev, -+ SHARED_KEY_MODE_ENTRY(i), 0); -++ rt2800_shared_mem_unlock(rt2x00dev); -+ -+ for (i = 0; i < 256; i++) { -+ rt2800_config_wcid(rt2x00dev, NULL, i); -+ rt2800_delete_wcid_attr(rt2x00dev, i); -++ -++ rt2800_shared_mem_lock(rt2x00dev); -+ rt2800_register_write(rt2x00dev, MAC_IVEIV_ENTRY(i), 0); -++ rt2800_shared_mem_unlock(rt2x00dev); -+ } -+ -+ /* -+@@ -5031,8 +5069,10 @@ static int rt2800_wait_bbp_ready(struct -+ * BBP was enabled after firmware was loaded, -+ * but we need to reactivate it now. -+ */ -++ rt2800_shared_mem_lock(rt2x00dev); -+ rt2800_register_write(rt2x00dev, H2M_BBP_AGENT, 0); -+ rt2800_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0); -++ rt2800_shared_mem_unlock(rt2x00dev); -+ msleep(1); -+ -+ for (i = 0; i < REGISTER_BUSY_COUNT; i++) { -+@@ -6728,11 +6768,19 @@ int rt2800_enable_radio(struct rt2x00_de -+ /* -+ * Send signal during boot time to initialize firmware. -+ */ -++ rt2800_shared_mem_lock(rt2x00dev); -+ rt2800_register_write(rt2x00dev, H2M_BBP_AGENT, 0); -+ rt2800_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0); -+- if (rt2x00_is_usb(rt2x00dev)) -++ rt2800_shared_mem_unlock(rt2x00dev); -++ -++ if (rt2x00_is_usb(rt2x00dev)) { -++ rt2800_shared_mem_lock(rt2x00dev); -+ rt2800_register_write(rt2x00dev, H2M_INT_SRC, 0); -++ rt2800_shared_mem_unlock(rt2x00dev); -++ } -++ -+ rt2800_mcu_request(rt2x00dev, MCU_BOOT_SIGNAL, 0, 0, 0); -++ -+ msleep(1); -+ -+ /* -+@@ -7738,6 +7786,8 @@ int rt2800_probe_hw(struct rt2x00_dev *r -+ int retval; -+ u32 reg; -+ -++ rt2800_shared_mem_init_lock(rt2x00dev); -++ -+ retval = rt2800_probe_rt(rt2x00dev); -+ if (retval) -+ return retval; -+@@ -7817,8 +7867,11 @@ void rt2800_get_tkip_seq(struct ieee8021 -+ u32 offset; -+ -+ offset = MAC_IVEIV_ENTRY(hw_key_idx); -++ -++ rt2800_shared_mem_lock(rt2x00dev); -+ rt2800_register_multiread(rt2x00dev, offset, -+ &iveiv_entry, sizeof(iveiv_entry)); -++ rt2800_shared_mem_unlock(rt2x00dev); -+ -+ memcpy(iv16, &iveiv_entry.iv[0], sizeof(*iv16)); -+ memcpy(iv32, &iveiv_entry.iv[4], sizeof(*iv32)); -+--- a/drivers/net/wireless/rt2x00/rt2800lib.h -++++ b/drivers/net/wireless/rt2x00/rt2800lib.h -+@@ -35,6 +35,11 @@ struct rt2800_drv_data { -+ unsigned int tbtt_tick; -+ -+ unsigned long rt2800_flags; -++ -++ union { -++ spinlock_t spin; -++ struct mutex mutex; -++ } shmem_lock; -+ }; -+ -+ struct rt2800_ops { -+@@ -65,6 +70,10 @@ struct rt2800_ops { -+ const u8 *data, const size_t len); -+ int (*drv_init_registers)(struct rt2x00_dev *rt2x00dev); -+ __le32 *(*drv_get_txwi)(struct queue_entry *entry); -++ -++ void (*shmem_init_lock)(struct rt2x00_dev *rt2x00dev); -++ void (*shmem_lock)(struct rt2x00_dev *rt2x00dev); -++ void (*shmem_unlock)(struct rt2x00_dev *rt2x00dev); -+ }; -+ -+ static inline bool rt2800_has_high_shared_mem(struct rt2x00_dev *rt2x00dev) -+@@ -74,6 +83,29 @@ static inline bool rt2800_has_high_share -+ return test_bit(RT2800_HAS_HIGH_SHARED_MEM, &drv_data->rt2800_flags); -+ } -+ -++static inline void rt2800_shared_mem_init_lock(struct rt2x00_dev *rt2x00dev) -++{ -++ const struct rt2800_ops *rt2800ops = rt2x00dev->ops->drv; -++ -++ rt2800ops->shmem_init_lock(rt2x00dev); -++} -++ -++static inline void rt2800_shared_mem_lock(struct rt2x00_dev *rt2x00dev) -++{ -++ const struct rt2800_ops *rt2800ops = rt2x00dev->ops->drv; -++ -++ if (rt2800_has_high_shared_mem(rt2x00dev)) -++ rt2800ops->shmem_lock(rt2x00dev); -++} -++ -++static inline void rt2800_shared_mem_unlock(struct rt2x00_dev *rt2x00dev) -++{ -++ const struct rt2800_ops *rt2800ops = rt2x00dev->ops->drv; -++ -++ if (rt2800_has_high_shared_mem(rt2x00dev)) -++ rt2800ops->shmem_unlock(rt2x00dev); -++} -++ -+ static inline void rt2800_register_read(struct rt2x00_dev *rt2x00dev, -+ const unsigned int offset, -+ u32 *value) -+--- a/drivers/net/wireless/rt2x00/rt2800mmio.c -++++ b/drivers/net/wireless/rt2x00/rt2800mmio.c -+@@ -820,8 +820,10 @@ int rt2800mmio_init_registers(struct rt2 -+ rt2x00_set_field32(®, WPDMA_RST_IDX_DRX_IDX0, 1); -+ rt2x00mmio_register_write(rt2x00dev, WPDMA_RST_IDX, reg); -+ -++ rt2800_shared_mem_lock(rt2x00dev); -+ rt2x00mmio_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e1f); -+ rt2x00mmio_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e00); -++ rt2800_shared_mem_unlock(rt2x00dev); -+ -+ if (rt2x00_is_pcie(rt2x00dev) && -+ (rt2x00_rt(rt2x00dev, RT3090) || -+@@ -865,6 +867,30 @@ int rt2800mmio_enable_radio(struct rt2x0 -+ } -+ EXPORT_SYMBOL_GPL(rt2800mmio_enable_radio); -+ -++void rt2800mmio_shmem_init_lock(struct rt2x00_dev *rt2x00dev) -++{ -++ struct rt2800_drv_data *drv_data = rt2x00dev->drv_data; -++ -++ spin_lock_init(&drv_data->shmem_lock.spin); -++} -++EXPORT_SYMBOL_GPL(rt2800mmio_shmem_init_lock); -++ -++void rt2800mmio_shmem_lock(struct rt2x00_dev *rt2x00dev) -++{ -++ struct rt2800_drv_data *drv_data = rt2x00dev->drv_data; -++ -++ spin_lock_bh(&drv_data->shmem_lock.spin); -++} -++EXPORT_SYMBOL_GPL(rt2800mmio_shmem_lock); -++ -++void rt2800mmio_shmem_unlock(struct rt2x00_dev *rt2x00dev) -++{ -++ struct rt2800_drv_data *drv_data = rt2x00dev->drv_data; -++ -++ spin_unlock_bh(&drv_data->shmem_lock.spin); -++} -++EXPORT_SYMBOL_GPL(rt2800mmio_shmem_unlock); -++ -+ MODULE_AUTHOR(DRV_PROJECT); -+ MODULE_VERSION(DRV_VERSION); -+ MODULE_DESCRIPTION("rt2800 MMIO library"); -+--- a/drivers/net/wireless/rt2x00/rt2800mmio.h -++++ b/drivers/net/wireless/rt2x00/rt2800mmio.h -+@@ -160,4 +160,8 @@ int rt2800mmio_init_registers(struct rt2 -+ /* Device state switch handlers. */ -+ int rt2800mmio_enable_radio(struct rt2x00_dev *rt2x00dev); -+ -++void rt2800mmio_shmem_init_lock(struct rt2x00_dev *rt2x00dev); -++void rt2800mmio_shmem_lock(struct rt2x00_dev *rt2x00dev); -++void rt2800mmio_shmem_unlock(struct rt2x00_dev *rt2x00dev); -++ -+ #endif /* RT2800MMIO_H */ -+--- a/drivers/net/wireless/rt2x00/rt2800pci.c -++++ b/drivers/net/wireless/rt2x00/rt2800pci.c -+@@ -69,7 +69,9 @@ static void rt2800pci_mcu_status(struct -+ return; -+ -+ for (i = 0; i < 200; i++) { -++ rt2800_shared_mem_lock(rt2x00dev); -+ rt2x00mmio_register_read(rt2x00dev, H2M_MAILBOX_CID, ®); -++ rt2800_shared_mem_unlock(rt2x00dev); -+ -+ if ((rt2x00_get_field32(reg, H2M_MAILBOX_CID_CMD0) == token) || -+ (rt2x00_get_field32(reg, H2M_MAILBOX_CID_CMD1) == token) || -+@@ -83,8 +85,10 @@ static void rt2800pci_mcu_status(struct -+ if (i == 200) -+ rt2x00_err(rt2x00dev, "MCU request failed, no response from hardware\n"); -+ -++ rt2800_shared_mem_lock(rt2x00dev); -+ rt2x00mmio_register_write(rt2x00dev, H2M_MAILBOX_STATUS, ~0); -+ rt2x00mmio_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0); -++ rt2800_shared_mem_unlock(rt2x00dev); -+ } -+ -+ static void rt2800pci_eepromregister_read(struct eeprom_93cx6 *eeprom) -+@@ -184,6 +188,8 @@ static int rt2800pci_write_firmware(stru -+ */ -+ reg = 0; -+ rt2x00_set_field32(®, PBF_SYS_CTRL_HOST_RAM_WRITE, 1); -++ -++ rt2800_shared_mem_lock(rt2x00dev); -+ rt2x00mmio_register_write(rt2x00dev, PBF_SYS_CTRL, reg); -+ -+ /* -+@@ -197,6 +203,7 @@ static int rt2800pci_write_firmware(stru -+ -+ rt2x00mmio_register_write(rt2x00dev, H2M_BBP_AGENT, 0); -+ rt2x00mmio_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0); -++ rt2800_shared_mem_unlock(rt2x00dev); -+ -+ return 0; -+ } -+@@ -213,8 +220,10 @@ static int rt2800pci_enable_radio(struct -+ return retval; -+ -+ /* After resume MCU_BOOT_SIGNAL will trash these. */ -++ rt2800_shared_mem_lock(rt2x00dev); -+ rt2x00mmio_register_write(rt2x00dev, H2M_MAILBOX_STATUS, ~0); -+ rt2x00mmio_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0); -++ rt2800_shared_mem_unlock(rt2x00dev); -+ -+ rt2800_mcu_request(rt2x00dev, MCU_SLEEP, TOKEN_RADIO_OFF, 0xff, 0x02); -+ rt2800pci_mcu_status(rt2x00dev, TOKEN_RADIO_OFF); -+@@ -233,10 +242,12 @@ static int rt2800pci_set_state(struct rt -+ 0, 0x02); -+ rt2800pci_mcu_status(rt2x00dev, TOKEN_WAKEUP); -+ } else if (state == STATE_SLEEP) { -++ rt2800_shared_mem_lock(rt2x00dev); -+ rt2x00mmio_register_write(rt2x00dev, H2M_MAILBOX_STATUS, -+ 0xffffffff); -+ rt2x00mmio_register_write(rt2x00dev, H2M_MAILBOX_CID, -+ 0xffffffff); -++ rt2800_shared_mem_unlock(rt2x00dev); -+ rt2800_mcu_request(rt2x00dev, MCU_SLEEP, TOKEN_SLEEP, -+ 0xff, 0x01); -+ } -+@@ -337,6 +348,9 @@ static const struct rt2800_ops rt2800pci -+ .drv_write_firmware = rt2800pci_write_firmware, -+ .drv_init_registers = rt2800mmio_init_registers, -+ .drv_get_txwi = rt2800mmio_get_txwi, -++ .shmem_init_lock = rt2800mmio_shmem_init_lock, -++ .shmem_lock = rt2800mmio_shmem_lock, -++ .shmem_unlock = rt2800mmio_shmem_unlock, -+ }; -+ -+ static const struct rt2x00lib_ops rt2800pci_rt2x00_ops = { -+--- a/drivers/net/wireless/rt2x00/rt2800soc.c -++++ b/drivers/net/wireless/rt2x00/rt2800soc.c -+@@ -176,6 +176,9 @@ static const struct rt2800_ops rt2800soc -+ .drv_write_firmware = rt2800soc_write_firmware, -+ .drv_init_registers = rt2800mmio_init_registers, -+ .drv_get_txwi = rt2800mmio_get_txwi, -++ .shmem_init_lock = rt2800mmio_shmem_init_lock, -++ .shmem_lock = rt2800mmio_shmem_lock, -++ .shmem_unlock = rt2800mmio_shmem_unlock, -+ }; -+ -+ static const struct rt2x00lib_ops rt2800soc_rt2x00_ops = { -+--- a/drivers/net/wireless/rt2x00/rt2800usb.c -++++ b/drivers/net/wireless/rt2x00/rt2800usb.c -+@@ -51,6 +51,27 @@ static bool rt2800usb_hwcrypt_disabled(s -+ return modparam_nohwcrypt; -+ } -+ -++static void rt2800usb_shmem_init_lock(struct rt2x00_dev *rt2x00dev) -++{ -++ struct rt2800_drv_data *drv_data = rt2x00dev->drv_data; -++ -++ mutex_init(&drv_data->shmem_lock.mutex); -++} -++ -++static void rt2800usb_shmem_lock(struct rt2x00_dev *rt2x00dev) -++{ -++ struct rt2800_drv_data *drv_data = rt2x00dev->drv_data; -++ -++ mutex_lock(&drv_data->shmem_lock.mutex); -++} -++ -++static void rt2800usb_shmem_unlock(struct rt2x00_dev *rt2x00dev) -++{ -++ struct rt2800_drv_data *drv_data = rt2x00dev->drv_data; -++ -++ mutex_unlock(&drv_data->shmem_lock.mutex); -++} -++ -+ /* -+ * Queue handlers. -+ */ -+@@ -260,8 +281,10 @@ static int rt2800usb_write_firmware(stru -+ rt2x00usb_register_multiwrite(rt2x00dev, FIRMWARE_IMAGE_BASE, -+ data + offset, length); -+ -++ rt2800_shared_mem_lock(rt2x00dev); -+ rt2x00usb_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0); -+ rt2x00usb_register_write(rt2x00dev, H2M_MAILBOX_STATUS, ~0); -++ rt2800_shared_mem_unlock(rt2x00dev); -+ -+ /* -+ * Send firmware request to device to load firmware, -+@@ -276,7 +299,10 @@ static int rt2800usb_write_firmware(stru -+ } -+ -+ msleep(10); -++ -++ rt2800_shared_mem_lock(rt2x00dev); -+ rt2x00usb_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0); -++ rt2800_shared_mem_unlock(rt2x00dev); -+ -+ return 0; -+ } -+@@ -294,8 +320,10 @@ static int rt2800usb_init_registers(stru -+ if (rt2800_wait_csr_ready(rt2x00dev)) -+ return -EBUSY; -+ -++ rt2800_shared_mem_lock(rt2x00dev); -+ rt2x00usb_register_read(rt2x00dev, PBF_SYS_CTRL, ®); -+ rt2x00usb_register_write(rt2x00dev, PBF_SYS_CTRL, reg & ~0x00002000); -++ rt2800_shared_mem_unlock(rt2x00dev); -+ -+ reg = 0; -+ rt2x00_set_field32(®, MAC_SYS_CTRL_RESET_CSR, 1); -+@@ -810,6 +838,9 @@ static const struct rt2800_ops rt2800usb -+ .drv_write_firmware = rt2800usb_write_firmware, -+ .drv_init_registers = rt2800usb_init_registers, -+ .drv_get_txwi = rt2800usb_get_txwi, -++ .shmem_init_lock = rt2800usb_shmem_init_lock, -++ .shmem_lock = rt2800usb_shmem_lock, -++ .shmem_unlock = rt2800usb_shmem_unlock, -+ }; -+ -+ static const struct rt2x00lib_ops rt2800usb_rt2x00_ops = { -diff --git a/package/mac80211/patches/600-0004-rt2x00-rt2800lib-fix-beacon-generation-on-RT3593.patch b/package/mac80211/patches/600-0004-rt2x00-rt2800lib-fix-beacon-generation-on-RT3593.patch -new file mode 100644 -index 0000000..7167f28 ---- /dev/null -+++ b/package/mac80211/patches/600-0004-rt2x00-rt2800lib-fix-beacon-generation-on-RT3593.patch -@@ -0,0 +1,131 @@ -+From dcfe3dd46242050f100162dce2bcad24d2c942c6 Mon Sep 17 00:00:00 2001 -+From: Gabor Juhos -+Date: Sat, 17 Aug 2013 19:31:42 +0200 -+Subject: [PATCH] rt2x00: rt2800lib: fix beacon generation on RT3593 -+ -+On the RT3593 chipset, the beacon registers are located -+in the high 8KB part of the shared memory. -+ -+The high part of the shared memory is only accessible -+if it is explicitly selected. Add a helper function -+in order to be able to control the SHR_MSEL bit in -+the PBF_SYS_CTRL register. Also add a few more helper -+functions and use those to select the correct part of -+the shared memory before and after accessing the beacon -+registers. -+ -+The base addresses of the beacon registers are also -+different from the actually used values, so fix the -+'rt2800_hw_beacon_base' function to return the correct -+values. -+ -+Signed-off-by: Gabor Juhos -+--- -+Changes since v1: --- -+--- -+ drivers/net/wireless/rt2x00/rt2800.h | 3 +++ -+ drivers/net/wireless/rt2x00/rt2800lib.c | 44 +++++++++++++++++++++++++++++++ -+ 2 files changed, 47 insertions(+) -+ -+--- a/drivers/net/wireless/rt2x00/rt2800.h -++++ b/drivers/net/wireless/rt2x00/rt2800.h -+@@ -572,6 +572,7 @@ -+ #define PBF_SYS_CTRL 0x0400 -+ #define PBF_SYS_CTRL_READY FIELD32(0x00000080) -+ #define PBF_SYS_CTRL_HOST_RAM_WRITE FIELD32(0x00010000) -++#define PBF_SYS_CTRL_SHR_MSEL FIELD32(0x00080000) -+ -+ /* -+ * HOST-MCU shared memory -+@@ -2024,6 +2025,8 @@ struct mac_iveiv_entry { -+ (((__index) < 6) ? (HW_BEACON_BASE4 + ((__index - 4) * 0x0200)) : \ -+ (HW_BEACON_BASE6 - ((__index - 6) * 0x0200)))) -+ -++#define HW_BEACON_BASE_HIGH(__index) (0x4000 + (__index) * 512) -++ -+ #define BEACON_BASE_TO_OFFSET(_base) (((_base) - 0x4000) / 64) -+ -+ /* -+--- a/drivers/net/wireless/rt2x00/rt2800lib.c -++++ b/drivers/net/wireless/rt2x00/rt2800lib.c -+@@ -82,6 +82,39 @@ static inline bool rt2800_is_305x_soc(st -+ return false; -+ } -+ -++static inline void rt2800_shared_mem_select(struct rt2x00_dev *rt2x00dev, -++ bool high) -++{ -++ u32 reg; -++ -++ if (WARN_ON_ONCE(!rt2800_has_high_shared_mem(rt2x00dev))) -++ return; -++ -++ rt2800_register_read(rt2x00dev, PBF_SYS_CTRL, ®); -++ rt2x00_set_field32(®, PBF_SYS_CTRL_SHR_MSEL, high); -++ rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, reg); -++} -++ -++static inline bool rt2800_beacon_uses_high_mem(struct rt2x00_dev *rt2x00dev) -++{ -++ if (rt2x00_rt(rt2x00dev, RT3593)) -++ return true; -++ -++ return false; -++} -++ -++static inline void rt2800_select_beacon_mem(struct rt2x00_dev *rt2x00dev) -++{ -++ if (rt2800_beacon_uses_high_mem(rt2x00dev)) -++ rt2800_shared_mem_select(rt2x00dev, true); -++} -++ -++static inline void rt2800_deselect_beacon_mem(struct rt2x00_dev *rt2x00dev) -++{ -++ if (rt2800_beacon_uses_high_mem(rt2x00dev)) -++ rt2800_shared_mem_select(rt2x00dev, false); -++} -++ -+ static void rt2800_bbp_write(struct rt2x00_dev *rt2x00dev, -+ const unsigned int word, const u8 value) -+ { -+@@ -948,6 +981,9 @@ EXPORT_SYMBOL_GPL(rt2800_txdone_entry); -+ static unsigned int rt2800_hw_beacon_base(struct rt2x00_dev *rt2x00dev, -+ unsigned int index) -+ { -++ if (rt2x00_rt(rt2x00dev, RT3593)) -++ return HW_BEACON_BASE_HIGH(index); -++ -+ return HW_BEACON_BASE(index); -+ } -+ -+@@ -1046,8 +1082,12 @@ void rt2800_write_beacon(struct queue_en -+ beacon_base = rt2800_hw_beacon_base(rt2x00dev, entry->entry_idx); -+ -+ rt2800_shared_mem_lock(rt2x00dev); -++ -++ rt2800_select_beacon_mem(rt2x00dev); -+ rt2800_register_multiwrite(rt2x00dev, beacon_base, entry->skb->data, -+ entry->skb->len + padding_len); -++ rt2800_deselect_beacon_mem(rt2x00dev); -++ -+ rt2800_shared_mem_unlock(rt2x00dev); -+ __set_bit(ENTRY_BCN_ENABLED, &entry->flags); -+ -+@@ -1080,6 +1120,8 @@ static inline void rt2800_clear_beacon_r -+ -+ rt2800_shared_mem_lock(rt2x00dev); -+ -++ rt2800_select_beacon_mem(rt2x00dev); -++ -+ /* -+ * For the Beacon base registers we only need to clear -+ * the whole TXWI which (when set to 0) will invalidate -+@@ -1088,6 +1130,8 @@ static inline void rt2800_clear_beacon_r -+ for (i = 0; i < txwi_desc_size; i += sizeof(__le32)) -+ rt2800_register_write(rt2x00dev, beacon_base + i, 0); -+ -++ rt2800_deselect_beacon_mem(rt2x00dev); -++ -+ rt2800_shared_mem_unlock(rt2x00dev); -+ } -+ -diff --git a/package/mac80211/patches/600-0005-rt2x00-rt2800lib-add-hw_beacon_count-field-to-struct.patch b/package/mac80211/patches/600-0005-rt2x00-rt2800lib-add-hw_beacon_count-field-to-struct.patch -new file mode 100644 -index 0000000..0b509df ---- /dev/null -+++ b/package/mac80211/patches/600-0005-rt2x00-rt2800lib-add-hw_beacon_count-field-to-struct.patch -@@ -0,0 +1,62 @@ -+From a058825fa7b53fab3b003d8928b60e5b686b3421 Mon Sep 17 00:00:00 2001 -+From: Gabor Juhos -+Date: Sun, 4 Aug 2013 14:36:11 +0200 -+Subject: [PATCH] rt2x00: rt2800lib: add hw_beacon_count field to struct -+ rt2800_drv_data -+ -+Some chipsets can handle more than 8 beacons at once. -+Add a new field to the rt2800_drv_data structure which -+will hold the number of supported beacons of the given -+chipset. -+ -+Update the rt2x00_init_registers function to get the -+beacon count from the new field instead of using a -+hardcoded value. -+ -+In order to keep the current behaviour, initialize the -+new field with the actually used value. -+ -+Signed-off-by: Gabor Juhos -+--- -+ drivers/net/wireless/rt2x00/rt2800lib.c | 5 ++++- -+ drivers/net/wireless/rt2x00/rt2800lib.h | 1 + -+ 2 files changed, 5 insertions(+), 1 deletion(-) -+ -+--- a/drivers/net/wireless/rt2x00/rt2800lib.c -++++ b/drivers/net/wireless/rt2x00/rt2800lib.c -+@@ -4628,6 +4628,7 @@ EXPORT_SYMBOL_GPL(rt2800_link_tuner); -+ */ -+ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) -+ { -++ struct rt2800_drv_data *drv_data = rt2x00dev->drv_data; -+ u32 reg; -+ u16 eeprom; -+ unsigned int i; -+@@ -4993,7 +4994,7 @@ static int rt2800_init_registers(struct -+ /* -+ * Clear all beacons -+ */ -+- for (i = 0; i < 8; i++) -++ for (i = 0; i < drv_data->hw_beacon_count; i++) -+ rt2800_clear_beacon_register(rt2x00dev, i); -+ -+ if (rt2x00_is_usb(rt2x00dev)) { -+@@ -7839,6 +7840,8 @@ int rt2800_probe_hw(struct rt2x00_dev *r -+ if (rt2x00_rt(rt2x00dev, RT3593)) -+ __set_bit(RT2800_HAS_HIGH_SHARED_MEM, &drv_data->rt2800_flags); -+ -++ drv_data->hw_beacon_count = 8; -++ -+ /* -+ * Allocate eeprom data. -+ */ -+--- a/drivers/net/wireless/rt2x00/rt2800lib.h -++++ b/drivers/net/wireless/rt2x00/rt2800lib.h -+@@ -33,6 +33,7 @@ struct rt2800_drv_data { -+ u8 txmixer_gain_24g; -+ u8 txmixer_gain_5g; -+ unsigned int tbtt_tick; -++ unsigned int hw_beacon_count; -+ -+ unsigned long rt2800_flags; -+ -diff --git a/package/mac80211/patches/600-0006-rt2x00-rt2800lib-init-additional-beacon-offset-regis.patch b/package/mac80211/patches/600-0006-rt2x00-rt2800lib-init-additional-beacon-offset-regis.patch -new file mode 100644 -index 0000000..95f44b5 ---- /dev/null -+++ b/package/mac80211/patches/600-0006-rt2x00-rt2800lib-init-additional-beacon-offset-regis.patch -@@ -0,0 +1,67 @@ -+From 1bfa43ca8f30be53ce4fa79cfc3e219642a812b6 Mon Sep 17 00:00:00 2001 -+From: Gabor Juhos -+Date: Mon, 2 Sep 2013 10:58:32 +0200 -+Subject: [PATCH] rt2x00: rt2800lib: init additional beacon offset registers -+ -+Signed-off-by: Gabor Juhos -+--- -+ drivers/net/wireless/rt2x00/rt2800.h | 14 ++++++++++++++ -+ drivers/net/wireless/rt2x00/rt2800lib.c | 24 ++++++++++++++++++++++++ -+ 2 files changed, 38 insertions(+) -+ -+--- a/drivers/net/wireless/rt2x00/rt2800.h -++++ b/drivers/net/wireless/rt2x00/rt2800.h -+@@ -627,6 +627,20 @@ -+ */ -+ #define PBF_DBG 0x043c -+ -++/* BCN_OFFSET2 */ -++#define BCN_OFFSET2 0x0444 -++#define BCN_OFFSET2_BCN8 FIELD32(0x000000ff) -++#define BCN_OFFSET2_BCN9 FIELD32(0x0000ff00) -++#define BCN_OFFSET2_BCN10 FIELD32(0x00ff0000) -++#define BCN_OFFSET2_BCN11 FIELD32(0xff000000) -++ -++/* BCN_OFFSET3 */ -++#define BCN_OFFSET3 0x0448 -++#define BCN_OFFSET3_BCN12 FIELD32(0x000000ff) -++#define BCN_OFFSET3_BCN13 FIELD32(0x0000ff00) -++#define BCN_OFFSET3_BCN14 FIELD32(0x00ff0000) -++#define BCN_OFFSET3_BCN15 FIELD32(0xff000000) -++ -+ /* -+ * RF registers -+ */ -+--- a/drivers/net/wireless/rt2x00/rt2800lib.c -++++ b/drivers/net/wireless/rt2x00/rt2800lib.c -+@@ -4640,6 +4640,30 @@ static int rt2800_init_registers(struct -+ if (ret) -+ return ret; -+ -++ if (drv_data->hw_beacon_count == 16) { -++ rt2800_register_read(rt2x00dev, BCN_OFFSET2, ®); -++ rt2x00_set_field32(®, BCN_OFFSET2_BCN8, -++ rt2800_get_beacon_offset(rt2x00dev, 8)); -++ rt2x00_set_field32(®, BCN_OFFSET2_BCN9, -++ rt2800_get_beacon_offset(rt2x00dev, 9)); -++ rt2x00_set_field32(®, BCN_OFFSET2_BCN10, -++ rt2800_get_beacon_offset(rt2x00dev, 10)); -++ rt2x00_set_field32(®, BCN_OFFSET2_BCN11, -++ rt2800_get_beacon_offset(rt2x00dev, 11)); -++ rt2800_register_write(rt2x00dev, BCN_OFFSET2, reg); -++ -++ rt2800_register_read(rt2x00dev, BCN_OFFSET3, ®); -++ rt2x00_set_field32(®, BCN_OFFSET3_BCN12, -++ rt2800_get_beacon_offset(rt2x00dev, 12)); -++ rt2x00_set_field32(®, BCN_OFFSET3_BCN13, -++ rt2800_get_beacon_offset(rt2x00dev, 13)); -++ rt2x00_set_field32(®, BCN_OFFSET3_BCN14, -++ rt2800_get_beacon_offset(rt2x00dev, 14)); -++ rt2x00_set_field32(®, BCN_OFFSET3_BCN15, -++ rt2800_get_beacon_offset(rt2x00dev, 15)); -++ rt2800_register_write(rt2x00dev, BCN_OFFSET3, reg); -++ } -++ -+ rt2800_register_write(rt2x00dev, LEGACY_BASIC_RATE, 0x0000013f); -+ rt2800_register_write(rt2x00dev, HT_BASIC_RATE, 0x00008003); -+ -diff --git a/package/mac80211/patches/600-0007-rt2x00-rt2800lib-fix-max-supported-beacon-count-for-.patch b/package/mac80211/patches/600-0007-rt2x00-rt2800lib-fix-max-supported-beacon-count-for-.patch -new file mode 100644 -index 0000000..303d2be ---- /dev/null -+++ b/package/mac80211/patches/600-0007-rt2x00-rt2800lib-fix-max-supported-beacon-count-for-.patch -@@ -0,0 +1,24 @@ -+From 9bea8b61f6025cd633bd5ac71be258620b49bcb3 Mon Sep 17 00:00:00 2001 -+From: Gabor Juhos -+Date: Mon, 2 Sep 2013 11:00:06 +0200 -+Subject: [PATCH] rt2x00: rt2800lib: fix max supported beacon count for RT3593 -+ -+Signed-off-by: Gabor Juhos -+--- -+ drivers/net/wireless/rt2x00/rt2800lib.c | 5 ++++- -+ 1 file changed, 4 insertions(+), 1 deletion(-) -+ -+--- a/drivers/net/wireless/rt2x00/rt2800lib.c -++++ b/drivers/net/wireless/rt2x00/rt2800lib.c -+@@ -7864,7 +7864,10 @@ int rt2800_probe_hw(struct rt2x00_dev *r -+ if (rt2x00_rt(rt2x00dev, RT3593)) -+ __set_bit(RT2800_HAS_HIGH_SHARED_MEM, &drv_data->rt2800_flags); -+ -+- drv_data->hw_beacon_count = 8; -++ if (rt2x00_rt(rt2x00dev, RT3593)) -++ drv_data->hw_beacon_count = 16; -++ else -++ drv_data->hw_beacon_count = 8; -+ -+ /* -+ * Allocate eeprom data. -diff --git a/package/mac80211/patches/600-0008-rt2x00-allow-to-build-rt2800soc-module-for-RT3883.patch b/package/mac80211/patches/600-0008-rt2x00-allow-to-build-rt2800soc-module-for-RT3883.patch -new file mode 100644 -index 0000000..8a10c6e ---- /dev/null -+++ b/package/mac80211/patches/600-0008-rt2x00-allow-to-build-rt2800soc-module-for-RT3883.patch -@@ -0,0 +1,30 @@ -+From 91094ed065f7794886b4a5490fd6de942f036bb4 Mon Sep 17 00:00:00 2001 -+From: Gabor Juhos -+Date: Sun, 24 Mar 2013 19:26:26 +0100 -+Subject: [PATCH] rt2x00: allow to build rt2800soc module for RT3883 -+ -+Signed-off-by: Gabor Juhos -+--- -+ drivers/net/wireless/rt2x00/Kconfig | 2 +- -+ 1 file changed, 1 insertion(+), 1 deletion(-) -+ -+--- a/drivers/net/wireless/rt2x00/Kconfig -++++ b/drivers/net/wireless/rt2x00/Kconfig -+@@ -210,7 +210,7 @@ endif -+ config RT2800SOC -+ tristate "Ralink WiSoC support" -+ depends on m -+- depends on SOC_RT288X || SOC_RT305X -++ depends on SOC_RT288X || SOC_RT305X || SOC_RT3883 -+ select RT2X00_LIB_SOC -+ select RT2X00_LIB_MMIO -+ select RT2X00_LIB_CRYPTO -+@@ -245,7 +245,7 @@ config RT2X00_LIB_PCI -+ -+ config RT2X00_LIB_SOC -+ tristate "RT2x00 SoC support" -+- depends on SOC_RT288X || SOC_RT305X -++ depends on SOC_RT288X || SOC_RT305X || SOC_RT3883 -+ depends on m -+ select RT2X00_LIB -+ -diff --git a/package/mac80211/patches/600-0009-rt2x00-rt2800lib-enable-support-for-RT3883.patch b/package/mac80211/patches/600-0009-rt2x00-rt2800lib-enable-support-for-RT3883.patch -new file mode 100644 -index 0000000..848d95f ---- /dev/null -+++ b/package/mac80211/patches/600-0009-rt2x00-rt2800lib-enable-support-for-RT3883.patch -@@ -0,0 +1,20 @@ -+From 4f16582c93a71eba9d389e0f0a8aa9099a9587cd Mon Sep 17 00:00:00 2001 -+From: Gabor Juhos -+Date: Sun, 24 Mar 2013 19:26:26 +0100 -+Subject: [PATCH] rt2x00: rt2800lib: enable support for RT3883 -+ -+Signed-off-by: Gabor Juhos -+--- -+ drivers/net/wireless/rt2x00/rt2800lib.c | 1 + -+ 1 file changed, 1 insertion(+) -+ -+--- a/drivers/net/wireless/rt2x00/rt2800lib.c -++++ b/drivers/net/wireless/rt2x00/rt2800lib.c -+@@ -7834,6 +7834,7 @@ static int rt2800_probe_rt(struct rt2x00 -+ case RT3390: -+ case RT3572: -+ case RT3593: -++ case RT3883: -+ case RT5390: -+ case RT5392: -+ case RT5592: -diff --git a/package/mac80211/patches/600-0010-rt2x00-rt2800lib-add-rf_vals-for-RF3853.patch b/package/mac80211/patches/600-0010-rt2x00-rt2800lib-add-rf_vals-for-RF3853.patch -new file mode 100644 -index 0000000..4ccd47f ---- /dev/null -+++ b/package/mac80211/patches/600-0010-rt2x00-rt2800lib-add-rf_vals-for-RF3853.patch -@@ -0,0 +1,112 @@ -+From ecb394ccf248d8652c463133c4f404458a57a9c1 Mon Sep 17 00:00:00 2001 -+From: Gabor Juhos -+Date: Sun, 24 Mar 2013 19:26:26 +0100 -+Subject: [PATCH] rt2x00: rt2800lib: add rf_vals for RF3853 -+ -+Signed-off-by: Gabor Juhos -+--- -+ drivers/net/wireless/rt2x00/rt2800.h | 4 +- -+ drivers/net/wireless/rt2x00/rt2800lib.c | 65 +++++++++++++++++++++++++++++++ -+ 2 files changed, 68 insertions(+), 1 deletion(-) -+ -+--- a/drivers/net/wireless/rt2x00/rt2800.h -++++ b/drivers/net/wireless/rt2x00/rt2800.h -+@@ -48,7 +48,8 @@ -+ * RF2853 2.4G/5G 3T3R -+ * RF3320 2.4G 1T1R(RT3350/RT3370/RT3390) -+ * RF3322 2.4G 2T2R(RT3352/RT3371/RT3372/RT3391/RT3392) -+- * RF3053 2.4G/5G 3T3R(RT3883/RT3563/RT3573/RT3593/RT3662) -++ * RF3053 2.4G/5G 3T3R(RT3563/RT3573/RT3593) -++ * RF3853 2.4G/5G 3T3R(RT3883/RT3662) -+ * RF5592 2.4G/5G 2T2R -+ * RF3070 2.4G 1T1R -+ * RF5360 2.4G 1T1R -+@@ -71,6 +72,7 @@ -+ #define RF5592 0x000f -+ #define RF3070 0x3070 -+ #define RF3290 0x3290 -++#define RF3853 0x3853 -+ #define RF5360 0x5360 -+ #define RF5370 0x5370 -+ #define RF5372 0x5372 -+--- a/drivers/net/wireless/rt2x00/rt2800lib.c -++++ b/drivers/net/wireless/rt2x00/rt2800lib.c -+@@ -7454,6 +7454,66 @@ static const struct rf_channel rf_vals_3 -+ {173, 0x61, 0, 9}, -+ }; -+ -++static const struct rf_channel rf_vals_3853[] = { -++ {1, 241, 6, 2}, -++ {2, 241, 6, 7}, -++ {3, 242, 6, 2}, -++ {4, 242, 6, 7}, -++ {5, 243, 6, 2}, -++ {6, 243, 6, 7}, -++ {7, 244, 6, 2}, -++ {8, 244, 6, 7}, -++ {9, 245, 6, 2}, -++ {10, 245, 6, 7}, -++ {11, 246, 6, 2}, -++ {12, 246, 6, 7}, -++ {13, 247, 6, 2}, -++ {14, 248, 6, 4}, -++ -++ {36, 0x56, 8, 4}, -++ {38, 0x56, 8, 6}, -++ {40, 0x56, 8, 8}, -++ {44, 0x57, 8, 0}, -++ {46, 0x57, 8, 2}, -++ {48, 0x57, 8, 4}, -++ {52, 0x57, 8, 8}, -++ {54, 0x57, 8, 10}, -++ {56, 0x58, 8, 0}, -++ {60, 0x58, 8, 4}, -++ {62, 0x58, 8, 6}, -++ {64, 0x58, 8, 8}, -++ -++ {100, 0x5b, 8, 8}, -++ {102, 0x5b, 8, 10}, -++ {104, 0x5c, 8, 0}, -++ {108, 0x5c, 8, 4}, -++ {110, 0x5c, 8, 6}, -++ {112, 0x5c, 8, 8}, -++ {114, 0x5c, 8, 10}, -++ {116, 0x5d, 8, 0}, -++ {118, 0x5d, 8, 2}, -++ {120, 0x5d, 8, 4}, -++ {124, 0x5d, 8, 8}, -++ {126, 0x5d, 8, 10}, -++ {128, 0x5e, 8, 0}, -++ {132, 0x5e, 8, 4}, -++ {134, 0x5e, 8, 6}, -++ {136, 0x5e, 8, 8}, -++ {140, 0x5f, 8, 0}, -++ -++ {149, 0x5f, 8, 9}, -++ {151, 0x5f, 8, 11}, -++ {153, 0x60, 8, 1}, -++ {157, 0x60, 8, 5}, -++ {159, 0x60, 8, 7}, -++ {161, 0x60, 8, 9}, -++ {165, 0x61, 8, 1}, -++ {167, 0x61, 8, 3}, -++ {169, 0x61, 8, 5}, -++ {171, 0x61, 8, 7}, -++ {173, 0x61, 8, 9}, -++}; -++ -+ static const struct rf_channel rf_vals_5592_xtal20[] = { -+ /* Channel, N, K, mod, R */ -+ {1, 482, 4, 10, 3}, -+@@ -7682,6 +7742,11 @@ static int rt2800_probe_hw_mode(struct r -+ spec->channels = rf_vals_3x; -+ break; -+ -++ case RF3853: -++ spec->num_channels = ARRAY_SIZE(rf_vals_3853); -++ spec->channels = rf_vals_3853; -++ break; -++ -+ case RF5592: -+ rt2800_register_read(rt2x00dev, MAC_DEBUG_INDEX, ®); -+ if (rt2x00_get_field32(reg, MAC_DEBUG_INDEX_XTAL)) { -diff --git a/package/mac80211/patches/600-0011-rt2x00-rt2800lib-enable-VCO-calibration-for-RF3853.patch b/package/mac80211/patches/600-0011-rt2x00-rt2800lib-enable-VCO-calibration-for-RF3853.patch -new file mode 100644 -index 0000000..7dbfd7f ---- /dev/null -+++ b/package/mac80211/patches/600-0011-rt2x00-rt2800lib-enable-VCO-calibration-for-RF3853.patch -@@ -0,0 +1,28 @@ -+From f8e3fcf18e1f2d7f9e6a9680c5452da090f33d88 Mon Sep 17 00:00:00 2001 -+From: Gabor Juhos -+Date: Thu, 1 Aug 2013 14:40:44 +0200 -+Subject: [PATCH] rt2x00: rt2800lib: enable VCO calibration for RF3853 -+ -+Signed-off-by: Gabor Juhos -+--- -+ drivers/net/wireless/rt2x00/rt2800lib.c | 2 ++ -+ 1 file changed, 2 insertions(+) -+ -+--- a/drivers/net/wireless/rt2x00/rt2800lib.c -++++ b/drivers/net/wireless/rt2x00/rt2800lib.c -+@@ -4393,6 +4393,7 @@ void rt2800_vco_calibration(struct rt2x0 -+ case RF3053: -+ case RF3070: -+ case RF3290: -++ case RF3853: -+ case RF5360: -+ case RF5370: -+ case RF5372: -+@@ -7861,6 +7862,7 @@ static int rt2800_probe_hw_mode(struct r -+ case RF3053: -+ case RF3070: -+ case RF3290: -++ case RF3853: -+ case RF5360: -+ case RF5370: -+ case RF5372: -diff --git a/package/mac80211/patches/600-0012-rt2x00-rt2800lib-add-channel-configuration-function-.patch b/package/mac80211/patches/600-0012-rt2x00-rt2800lib-add-channel-configuration-function-.patch -new file mode 100644 -index 0000000..4c28f9b ---- /dev/null -+++ b/package/mac80211/patches/600-0012-rt2x00-rt2800lib-add-channel-configuration-function-.patch -@@ -0,0 +1,235 @@ -+From 6e3a17190815c6aa4dc53c2cfe9125fb1154f187 Mon Sep 17 00:00:00 2001 -+From: Gabor Juhos -+Date: Sun, 24 Mar 2013 19:26:27 +0100 -+Subject: [PATCH] rt2x00: rt2800lib: add channel configuration function for -+ RF3853 -+ -+Signed-off-by: Gabor Juhos -+--- -+ drivers/net/wireless/rt2x00/rt2800lib.c | 208 +++++++++++++++++++++++++++++++ -+ 1 file changed, 208 insertions(+) -+ -+--- a/drivers/net/wireless/rt2x00/rt2800lib.c -++++ b/drivers/net/wireless/rt2x00/rt2800lib.c -+@@ -2649,6 +2649,211 @@ static void rt2800_config_channel_rf3053 -+ } -+ } -+ -++static void rt2800_config_channel_rf3853(struct rt2x00_dev *rt2x00dev, -++ struct ieee80211_conf *conf, -++ struct rf_channel *rf, -++ struct channel_info *info) -++{ -++ u8 rfcsr; -++ u8 bbp; -++ u8 pwr1, pwr2, pwr3; -++ -++ const bool txbf_enabled = false; /* TODO */ -++ -++ /* TODO: add band selection */ -++ -++ if (rf->channel <= 14) -++ rt2800_rfcsr_write(rt2x00dev, 6, 0x40); -++ else if (rf->channel < 132) -++ rt2800_rfcsr_write(rt2x00dev, 6, 0x80); -++ else -++ rt2800_rfcsr_write(rt2x00dev, 6, 0x40); -++ -++ rt2800_rfcsr_write(rt2x00dev, 8, rf->rf1); -++ rt2800_rfcsr_write(rt2x00dev, 9, rf->rf3); -++ -++ if (rf->channel <= 14) -++ rt2800_rfcsr_write(rt2x00dev, 11, 0x46); -++ else -++ rt2800_rfcsr_write(rt2x00dev, 11, 0x48); -++ -++ if (rf->channel <= 14) -++ rt2800_rfcsr_write(rt2x00dev, 12, 0x1a); -++ else -++ rt2800_rfcsr_write(rt2x00dev, 12, 0x52); -++ -++ rt2800_rfcsr_write(rt2x00dev, 13, 0x12); -++ -++ rt2800_rfcsr_read(rt2x00dev, 1, &rfcsr); -++ rt2x00_set_field8(&rfcsr, RFCSR1_RX0_PD, 0); -++ rt2x00_set_field8(&rfcsr, RFCSR1_TX0_PD, 0); -++ rt2x00_set_field8(&rfcsr, RFCSR1_RX1_PD, 0); -++ rt2x00_set_field8(&rfcsr, RFCSR1_TX1_PD, 0); -++ rt2x00_set_field8(&rfcsr, RFCSR1_RX2_PD, 0); -++ rt2x00_set_field8(&rfcsr, RFCSR1_TX2_PD, 0); -++ rt2x00_set_field8(&rfcsr, RFCSR1_RF_BLOCK_EN, 1); -++ rt2x00_set_field8(&rfcsr, RFCSR1_PLL_PD, 1); -++ -++ switch (rt2x00dev->default_ant.tx_chain_num) { -++ case 3: -++ rt2x00_set_field8(&rfcsr, RFCSR1_TX2_PD, 1); -++ /* fallthrough */ -++ case 2: -++ rt2x00_set_field8(&rfcsr, RFCSR1_TX1_PD, 1); -++ /* fallthrough */ -++ case 1: -++ rt2x00_set_field8(&rfcsr, RFCSR1_TX0_PD, 1); -++ break; -++ } -++ -++ switch (rt2x00dev->default_ant.rx_chain_num) { -++ case 3: -++ rt2x00_set_field8(&rfcsr, RFCSR1_RX2_PD, 1); -++ /* fallthrough */ -++ case 2: -++ rt2x00_set_field8(&rfcsr, RFCSR1_RX1_PD, 1); -++ /* fallthrough */ -++ case 1: -++ rt2x00_set_field8(&rfcsr, RFCSR1_RX0_PD, 1); -++ break; -++ } -++ rt2800_rfcsr_write(rt2x00dev, 1, rfcsr); -++ -++ rt2800_adjust_freq_offset(rt2x00dev); -++ -++ rt2800_rfcsr_read(rt2x00dev, 30, &rfcsr); -++ if (!conf_is_ht40(conf)) -++ rfcsr &= ~(0x06); -++ else -++ rfcsr |= 0x06; -++ rt2800_rfcsr_write(rt2x00dev, 30, rfcsr); -++ -++ if (rf->channel <= 14) -++ rt2800_rfcsr_write(rt2x00dev, 31, 0xa0); -++ else -++ rt2800_rfcsr_write(rt2x00dev, 31, 0x80); -++ -++ if (conf_is_ht40(conf)) -++ rt2800_rfcsr_write(rt2x00dev, 32, 0x80); -++ else -++ rt2800_rfcsr_write(rt2x00dev, 32, 0xd8); -++ -++ if (rf->channel <= 14) -++ rt2800_rfcsr_write(rt2x00dev, 34, 0x3c); -++ else -++ rt2800_rfcsr_write(rt2x00dev, 34, 0x20); -++ -++ /* loopback RF_BS */ -++ rt2800_rfcsr_read(rt2x00dev, 36, &rfcsr); -++ if (rf->channel <= 14) -++ rt2x00_set_field8(&rfcsr, RFCSR36_RF_BS, 1); -++ else -++ rt2x00_set_field8(&rfcsr, RFCSR36_RF_BS, 0); -++ rt2800_rfcsr_write(rt2x00dev, 36, rfcsr); -++ -++ if (rf->channel <= 14) -++ rfcsr = 0x23; -++ else if (rf->channel < 100) -++ rfcsr = 0x36; -++ else if (rf->channel < 132) -++ rfcsr = 0x32; -++ else -++ rfcsr = 0x30; -++ -++ if (txbf_enabled) -++ rfcsr |= 0x40; -++ -++ rt2800_rfcsr_write(rt2x00dev, 39, rfcsr); -++ -++ if (rf->channel <= 14) -++ rt2800_rfcsr_write(rt2x00dev, 44, 0x93); -++ else -++ rt2800_rfcsr_write(rt2x00dev, 44, 0x9b); -++ -++ if (rf->channel <= 14) -++ rfcsr = 0xbb; -++ else if (rf->channel < 100) -++ rfcsr = 0xeb; -++ else if (rf->channel < 132) -++ rfcsr = 0xb3; -++ else -++ rfcsr = 0x9b; -++ rt2800_rfcsr_write(rt2x00dev, 45, rfcsr); -++ -++ if (rf->channel <= 14) -++ rfcsr = 0x8e; -++ else -++ rfcsr = 0x8a; -++ -++ if (txbf_enabled) -++ rfcsr |= 0x20; -++ -++ rt2800_rfcsr_write(rt2x00dev, 49, rfcsr); -++ -++ rt2800_rfcsr_write(rt2x00dev, 50, 0x86); -++ -++ rt2800_rfcsr_read(rt2x00dev, 51, &rfcsr); -++ if (rf->channel <= 14) -++ rt2800_rfcsr_write(rt2x00dev, 51, 0x75); -++ else -++ rt2800_rfcsr_write(rt2x00dev, 51, 0x51); -++ -++ rt2800_rfcsr_read(rt2x00dev, 52, &rfcsr); -++ if (rf->channel <= 14) -++ rt2800_rfcsr_write(rt2x00dev, 52, 0x45); -++ else -++ rt2800_rfcsr_write(rt2x00dev, 52, 0x05); -++ -++ if (rf->channel <= 14) { -++ pwr1 = info->default_power1 & 0x1f; -++ pwr2 = info->default_power2 & 0x1f; -++ pwr3 = info->default_power3 & 0x1f; -++ } else { -++ pwr1 = 0x48 | ((info->default_power1 & 0x18) << 1) | -++ (info->default_power1 & 0x7); -++ pwr2 = 0x48 | ((info->default_power2 & 0x18) << 1) | -++ (info->default_power2 & 0x7); -++ pwr3 = 0x48 | ((info->default_power3 & 0x18) << 1) | -++ (info->default_power3 & 0x7); -++ } -++ -++ rt2800_rfcsr_write(rt2x00dev, 53, pwr1); -++ rt2800_rfcsr_write(rt2x00dev, 54, pwr2); -++ rt2800_rfcsr_write(rt2x00dev, 55, pwr3); -++ -++ rt2x00_dbg(rt2x00dev, "Channel:%d, pwr1:%02x, pwr2:%02x, pwr3:%02x\n", -++ rf->channel, pwr1, pwr2, pwr3); -++ -++ bbp = (info->default_power1 >> 5) | -++ ((info->default_power2 & 0xe0) >> 1); -++ rt2800_bbp_write(rt2x00dev, 109, bbp); -++ -++ rt2800_bbp_read(rt2x00dev, 110, &bbp); -++ bbp &= 0x0f; -++ bbp |= (info->default_power3 & 0xe0) >> 1; -++ rt2800_bbp_write(rt2x00dev, 110, bbp); -++ -++ rt2800_rfcsr_read(rt2x00dev, 57, &rfcsr); -++ if (rf->channel <= 14) -++ rt2800_rfcsr_write(rt2x00dev, 57, 0x6e); -++ else -++ rt2800_rfcsr_write(rt2x00dev, 57, 0x3e); -++ -++ /* Enable RF tuning */ -++ rt2800_rfcsr_read(rt2x00dev, 3, &rfcsr); -++ rt2x00_set_field8(&rfcsr, RFCSR3_VCOCAL_EN, 1); -++ rt2800_rfcsr_write(rt2x00dev, 3, rfcsr); -++ -++ udelay(2000); -++ -++ rt2800_bbp_read(rt2x00dev, 49, &bbp); -++ /* clear update flag */ -++ rt2800_bbp_write(rt2x00dev, 49, bbp & 0xfe); -++ rt2800_bbp_write(rt2x00dev, 49, bbp); -++ -++ /* TODO: add calibration for TxBF */ -++} -++ -+ #define POWER_BOUND 0x27 -+ #define POWER_BOUND_5G 0x2b -+ -+@@ -3261,6 +3466,9 @@ static void rt2800_config_channel(struct -+ case RF3322: -+ rt2800_config_channel_rf3322(rt2x00dev, conf, rf, info); -+ break; -++ case RF3853: -++ rt2800_config_channel_rf3853(rt2x00dev, conf, rf, info); -++ break; -+ case RF3070: -+ case RF5360: -+ case RF5370: -diff --git a/package/mac80211/patches/600-0013-rt2x00-rt2800lib-enable-RF3853-support.patch b/package/mac80211/patches/600-0013-rt2x00-rt2800lib-enable-RF3853-support.patch -new file mode 100644 -index 0000000..9419e62 ---- /dev/null -+++ b/package/mac80211/patches/600-0013-rt2x00-rt2800lib-enable-RF3853-support.patch -@@ -0,0 +1,20 @@ -+From afd38ae82226551bf879b6c7c4b620c271fee9d2 Mon Sep 17 00:00:00 2001 -+From: Gabor Juhos -+Date: Thu, 1 Aug 2013 14:42:05 +0200 -+Subject: [PATCH] rt2x00: rt2800lib: enable RF3853 support -+ -+Signed-off-by: Gabor Juhos -+--- -+ drivers/net/wireless/rt2x00/rt2800lib.c | 1 + -+ 1 file changed, 1 insertion(+) -+ -+--- a/drivers/net/wireless/rt2x00/rt2800lib.c -++++ b/drivers/net/wireless/rt2x00/rt2800lib.c -+@@ -7420,6 +7420,7 @@ static int rt2800_init_eeprom(struct rt2 -+ case RF3290: -+ case RF3320: -+ case RF3322: -++ case RF3853: -+ case RF5360: -+ case RF5370: -+ case RF5372: -diff --git a/package/mac80211/patches/600-0014-rt2x00-rt2800lib-add-MAC-register-initialization-for.patch b/package/mac80211/patches/600-0014-rt2x00-rt2800lib-add-MAC-register-initialization-for.patch -new file mode 100644 -index 0000000..65c6720 ---- /dev/null -+++ b/package/mac80211/patches/600-0014-rt2x00-rt2800lib-add-MAC-register-initialization-for.patch -@@ -0,0 +1,77 @@ -+From 0094872a5e8e4664c6ea1b2dfa487063d39ae363 Mon Sep 17 00:00:00 2001 -+From: Gabor Juhos -+Date: Sun, 24 Mar 2013 19:26:26 +0100 -+Subject: [PATCH] rt2x00: rt2800lib: add MAC register initialization for -+ RT3883 -+ -+Signed-off-by: Gabor Juhos -+--- -+ drivers/net/wireless/rt2x00/rt2800.h | 14 ++++++++++++++ -+ drivers/net/wireless/rt2x00/rt2800lib.c | 19 ++++++++++++++++--- -+ 2 files changed, 30 insertions(+), 3 deletions(-) -+ -+--- a/drivers/net/wireless/rt2x00/rt2800.h -++++ b/drivers/net/wireless/rt2x00/rt2800.h -+@@ -1586,6 +1586,20 @@ -+ #define TX_PWR_CFG_9_STBC7_CH2 FIELD32(0x00000f00) -+ -+ /* -++ * TX_TXBF_CFG: -++ */ -++#define TX_TXBF_CFG_0 0x138c -++#define TX_TXBF_CFG_1 0x13a4 -++#define TX_TXBF_CFG_2 0x13a8 -++#define TX_TXBF_CFG_3 0x13ac -++ -++/* -++ * TX_FBK_CFG_3S: -++ */ -++#define TX_FBK_CFG_3S_0 0x13c4 -++#define TX_FBK_CFG_3S_1 0x13c8 -++ -++/* -+ * RX_FILTER_CFG: RX configuration register. -+ */ -+ #define RX_FILTER_CFG 0x1400 -+--- a/drivers/net/wireless/rt2x00/rt2800lib.c -++++ b/drivers/net/wireless/rt2x00/rt2800lib.c -+@@ -4995,6 +4995,12 @@ static int rt2800_init_registers(struct -+ rt2800_register_write(rt2x00dev, TX_SW_CFG2, -+ 0x00000000); -+ } -++ } else if (rt2x00_rt(rt2x00dev, RT3883)) { -++ rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000402); -++ rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00000000); -++ rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00040000); -++ rt2800_register_write(rt2x00dev, TX_TXBF_CFG_0, 0x8000fc21); -++ rt2800_register_write(rt2x00dev, TX_TXBF_CFG_3, 0x00009c40); -+ } else if (rt2x00_rt(rt2x00dev, RT5390) || -+ rt2x00_rt(rt2x00dev, RT5392) || -+ rt2x00_rt(rt2x00dev, RT5592)) { -+@@ -5025,9 +5031,11 @@ static int rt2800_init_registers(struct -+ -+ rt2800_register_read(rt2x00dev, MAX_LEN_CFG, ®); -+ rt2x00_set_field32(®, MAX_LEN_CFG_MAX_MPDU, AGGREGATION_SIZE); -+- if (rt2x00_rt_rev_gte(rt2x00dev, RT2872, REV_RT2872E) || -+- rt2x00_rt(rt2x00dev, RT2883) || -+- rt2x00_rt_rev_lt(rt2x00dev, RT3070, REV_RT3070E)) -++ if (rt2x00_rt(rt2x00dev, RT3883)) -++ rt2x00_set_field32(®, MAX_LEN_CFG_MAX_PSDU, 3); -++ else if (rt2x00_rt_rev_gte(rt2x00dev, RT2872, REV_RT2872E) || -++ rt2x00_rt(rt2x00dev, RT2883) || -++ rt2x00_rt_rev_lt(rt2x00dev, RT3070, REV_RT3070E)) -+ rt2x00_set_field32(®, MAX_LEN_CFG_MAX_PSDU, 2); -+ else -+ rt2x00_set_field32(®, MAX_LEN_CFG_MAX_PSDU, 1); -+@@ -5180,6 +5188,11 @@ static int rt2800_init_registers(struct -+ reg = rt2x00_rt(rt2x00dev, RT5592) ? 0x00000082 : 0x00000002; -+ rt2800_register_write(rt2x00dev, TXOP_HLDR_ET, reg); -+ -++ if (rt2x00_rt(rt2x00dev, RT3883)) { -++ rt2800_register_write(rt2x00dev, TX_FBK_CFG_3S_0, 0x12111008); -++ rt2800_register_write(rt2x00dev, TX_FBK_CFG_3S_1, 0x16151413); -++ } -++ -+ rt2800_register_read(rt2x00dev, TX_RTS_CFG, ®); -+ rt2x00_set_field32(®, TX_RTS_CFG_AUTO_RTS_RETRY_LIMIT, 32); -+ rt2x00_set_field32(®, TX_RTS_CFG_RTS_THRES, -diff --git a/package/mac80211/patches/600-0015-rt2x00-rt2800soc-fix-rt2800soc_disable_radio-for-RT3.patch b/package/mac80211/patches/600-0015-rt2x00-rt2800soc-fix-rt2800soc_disable_radio-for-RT3.patch -new file mode 100644 -index 0000000..837c025 ---- /dev/null -+++ b/package/mac80211/patches/600-0015-rt2x00-rt2800soc-fix-rt2800soc_disable_radio-for-RT3.patch -@@ -0,0 +1,30 @@ -+From 6c2d32478159fffff0b85abb6817a21bb2338231 Mon Sep 17 00:00:00 2001 -+From: Gabor Juhos -+Date: Sun, 24 Mar 2013 19:26:27 +0100 -+Subject: [PATCH] rt2x00: rt2800soc: fix rt2800soc_disable_radio for RT3883 -+ -+Signed-off-by: Gabor Juhos -+--- -+ drivers/net/wireless/rt2x00/rt2800soc.c | 9 ++++++++- -+ 1 file changed, 8 insertions(+), 1 deletion(-) -+ -+--- a/drivers/net/wireless/rt2x00/rt2800soc.c -++++ b/drivers/net/wireless/rt2x00/rt2800soc.c -+@@ -51,9 +51,16 @@ static bool rt2800soc_hwcrypt_disabled(s -+ -+ static void rt2800soc_disable_radio(struct rt2x00_dev *rt2x00dev) -+ { -++ u32 reg; -++ -+ rt2800_disable_radio(rt2x00dev); -+ rt2x00mmio_register_write(rt2x00dev, PWR_PIN_CFG, 0); -+- rt2x00mmio_register_write(rt2x00dev, TX_PIN_CFG, 0); -++ -++ reg = 0; -++ if (rt2x00_rt(rt2x00dev, RT3883)) -++ rt2x00_set_field32(®, TX_PIN_CFG_RFTR_EN, 1); -++ -++ rt2x00mmio_register_write(rt2x00dev, TX_PIN_CFG, reg); -+ } -+ -+ static int rt2800soc_set_device_state(struct rt2x00_dev *rt2x00dev, -diff --git a/package/mac80211/patches/600-0016-rt2x00-rt2800lib-add-BBP-register-initialization-for.patch b/package/mac80211/patches/600-0016-rt2x00-rt2800lib-add-BBP-register-initialization-for.patch -new file mode 100644 -index 0000000..bba96db ---- /dev/null -+++ b/package/mac80211/patches/600-0016-rt2x00-rt2800lib-add-BBP-register-initialization-for.patch -@@ -0,0 +1,71 @@ -+From 84833056aa7dd25f5b097e31c78f2a0914c5160c Mon Sep 17 00:00:00 2001 -+From: Gabor Juhos -+Date: Sun, 24 Mar 2013 19:26:26 +0100 -+Subject: [PATCH] rt2x00: rt2800lib: add BBP register initialization for -+ RT3883 -+ -+Signed-off-by: Gabor Juhos -+--- -+ drivers/net/wireless/rt2x00/rt2800lib.c | 44 +++++++++++++++++++++++++++++++ -+ 1 file changed, 44 insertions(+) -+ -+--- a/drivers/net/wireless/rt2x00/rt2800lib.c -++++ b/drivers/net/wireless/rt2x00/rt2800lib.c -+@@ -5798,6 +5798,47 @@ static void rt2800_init_bbp_3593(struct -+ rt2800_bbp_write(rt2x00dev, 103, 0xc0); -+ } -+ -++static void rt2800_init_bbp_3883(struct rt2x00_dev *rt2x00dev) -++{ -++ rt2800_init_bbp_early(rt2x00dev); -++ -++ rt2800_bbp_write(rt2x00dev, 4, 0x50); -++ rt2800_bbp_write(rt2x00dev, 47, 0x48); -++ -++ rt2800_bbp_write(rt2x00dev, 86, 0x46); -++ rt2800_bbp_write(rt2x00dev, 88, 0x90); -++ -++ rt2800_bbp_write(rt2x00dev, 92, 0x02); -++ -++ rt2800_bbp_write(rt2x00dev, 103, 0xc0); -++ rt2800_bbp_write(rt2x00dev, 104, 0x92); -++ rt2800_bbp_write(rt2x00dev, 105, 0x34); -++ rt2800_bbp_write(rt2x00dev, 106, 0x12); -++ rt2800_bbp_write(rt2x00dev, 120, 0x50); -++ rt2800_bbp_write(rt2x00dev, 137, 0x0f); -++ rt2800_bbp_write(rt2x00dev, 163, 0x9d); -++ -++ /* 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); -++} -++ -+ static void rt2800_init_bbp_53xx(struct rt2x00_dev *rt2x00dev) -+ { -+ int ant, div_mode; -+@@ -6016,6 +6057,9 @@ static void rt2800_init_bbp(struct rt2x0 -+ case RT3593: -+ rt2800_init_bbp_3593(rt2x00dev); -+ return; -++ case RT3883: -++ rt2800_init_bbp_3883(rt2x00dev); -++ return; -+ case RT5390: -+ case RT5392: -+ rt2800_init_bbp_53xx(rt2x00dev); -diff --git a/package/mac80211/patches/600-0017-rt2x00-rt2800lib-add-RFCSR-initialization-for-RT3883.patch b/package/mac80211/patches/600-0017-rt2x00-rt2800lib-add-RFCSR-initialization-for-RT3883.patch -new file mode 100644 -index 0000000..568e60e ---- /dev/null -+++ b/package/mac80211/patches/600-0017-rt2x00-rt2800lib-add-RFCSR-initialization-for-RT3883.patch -@@ -0,0 +1,178 @@ -+From 99c659cf345640fd0f733cbcaf4583cc2c868ec0 Mon Sep 17 00:00:00 2001 -+From: Gabor Juhos -+Date: Mon, 29 Apr 2013 13:21:48 +0200 -+Subject: [PATCH] rt2x00: rt2800lib: add RFCSR initialization for RT3883 -+ -+Signed-off-by: Gabor Juhos -+--- -+ drivers/net/wireless/rt2x00/rt2800.h | 1 + -+ drivers/net/wireless/rt2x00/rt2800lib.c | 141 +++++++++++++++++++++++++++++++ -+ 2 files changed, 142 insertions(+) -+ -+--- a/drivers/net/wireless/rt2x00/rt2800.h -++++ b/drivers/net/wireless/rt2x00/rt2800.h -+@@ -2169,6 +2169,7 @@ struct mac_iveiv_entry { -+ /* -+ * RFCSR 2: -+ */ -++#define RFCSR2_RESCAL_BP FIELD8(0x40) -+ #define RFCSR2_RESCAL_EN FIELD8(0x80) -+ -+ /* -+--- a/drivers/net/wireless/rt2x00/rt2800lib.c -++++ b/drivers/net/wireless/rt2x00/rt2800lib.c -+@@ -6833,6 +6833,144 @@ static void rt2800_init_rfcsr_3593(struc -+ /* TODO: enable stream mode support */ -+ } -+ -++static void rt2800_init_rfcsr_3883(struct rt2x00_dev *rt2x00dev) -++{ -++ u8 rfcsr; -++ -++ /* TODO: get the actual ECO value from the SoC */ -++ const unsigned int eco = 5; -++ -++ rt2800_rf_init_calibration(rt2x00dev, 2); -++ -++ rt2800_rfcsr_write(rt2x00dev, 0, 0xe0); -++ rt2800_rfcsr_write(rt2x00dev, 1, 0x03); -++ rt2800_rfcsr_write(rt2x00dev, 2, 0x50); -++ rt2800_rfcsr_write(rt2x00dev, 3, 0x20); -++ rt2800_rfcsr_write(rt2x00dev, 4, 0x00); -++ rt2800_rfcsr_write(rt2x00dev, 5, 0x00); -++ rt2800_rfcsr_write(rt2x00dev, 6, 0x40); -++ rt2800_rfcsr_write(rt2x00dev, 7, 0x00); -++ rt2800_rfcsr_write(rt2x00dev, 8, 0x5b); -++ rt2800_rfcsr_write(rt2x00dev, 9, 0x08); -++ rt2800_rfcsr_write(rt2x00dev, 10, 0xd3); -++ rt2800_rfcsr_write(rt2x00dev, 11, 0x48); -++ rt2800_rfcsr_write(rt2x00dev, 12, 0x1a); -++ rt2800_rfcsr_write(rt2x00dev, 13, 0x12); -++ rt2800_rfcsr_write(rt2x00dev, 14, 0x00); -++ rt2800_rfcsr_write(rt2x00dev, 15, 0x00); -++ rt2800_rfcsr_write(rt2x00dev, 16, 0x00); -++ -++ /* RFCSR 17 will be initialized later based on the -++ * frequency offset stored in the EEPROM -++ */ -++ -++ rt2800_rfcsr_write(rt2x00dev, 18, 0x40); -++ 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, 0xc0); -++ rt2800_rfcsr_write(rt2x00dev, 24, 0x00); -++ rt2800_rfcsr_write(rt2x00dev, 25, 0x00); -++ rt2800_rfcsr_write(rt2x00dev, 26, 0x00); -++ rt2800_rfcsr_write(rt2x00dev, 27, 0x00); -++ rt2800_rfcsr_write(rt2x00dev, 28, 0x00); -++ 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, 0x20); -++ rt2800_rfcsr_write(rt2x00dev, 35, 0x00); -++ rt2800_rfcsr_write(rt2x00dev, 36, 0x00); -++ rt2800_rfcsr_write(rt2x00dev, 37, 0x00); -++ rt2800_rfcsr_write(rt2x00dev, 38, 0x86); -++ rt2800_rfcsr_write(rt2x00dev, 39, 0x23); -++ rt2800_rfcsr_write(rt2x00dev, 40, 0x00); -++ rt2800_rfcsr_write(rt2x00dev, 41, 0x00); -++ rt2800_rfcsr_write(rt2x00dev, 42, 0x00); -++ rt2800_rfcsr_write(rt2x00dev, 43, 0x00); -++ rt2800_rfcsr_write(rt2x00dev, 44, 0x93); -++ rt2800_rfcsr_write(rt2x00dev, 45, 0xbb); -++ rt2800_rfcsr_write(rt2x00dev, 46, 0x60); -++ rt2800_rfcsr_write(rt2x00dev, 47, 0x00); -++ rt2800_rfcsr_write(rt2x00dev, 48, 0x00); -++ rt2800_rfcsr_write(rt2x00dev, 49, 0x8e); -++ rt2800_rfcsr_write(rt2x00dev, 50, 0x86); -++ rt2800_rfcsr_write(rt2x00dev, 51, 0x51); -++ rt2800_rfcsr_write(rt2x00dev, 52, 0x05); -++ rt2800_rfcsr_write(rt2x00dev, 53, 0x76); -++ rt2800_rfcsr_write(rt2x00dev, 54, 0x76); -++ rt2800_rfcsr_write(rt2x00dev, 55, 0x76); -++ rt2800_rfcsr_write(rt2x00dev, 56, 0xdb); -++ rt2800_rfcsr_write(rt2x00dev, 57, 0x3e); -++ rt2800_rfcsr_write(rt2x00dev, 58, 0x00); -++ 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); -++ -++ /* TODO: rx filter calibration? */ -++ -++ rt2800_bbp_write(rt2x00dev, 137, 0x0f); -++ -++ rt2800_bbp_write(rt2x00dev, 163, 0x9d); -++ -++ rt2800_bbp_write(rt2x00dev, 105, 0x05); -++ -++ 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); -++ -++ 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 (eco == 5) { -++ rt2800_rfcsr_write(rt2x00dev, 32, 0xd8); -++ rt2800_rfcsr_write(rt2x00dev, 33, 0x32); -++ } -++ -++ rt2800_rfcsr_read(rt2x00dev, 2, &rfcsr); -++ rt2x00_set_field8(&rfcsr, RFCSR2_RESCAL_BP, 0); -++ rt2x00_set_field8(&rfcsr, RFCSR2_RESCAL_EN, 1); -++ rt2800_rfcsr_write(rt2x00dev, 2, rfcsr); -++ msleep(1); -++ rt2x00_set_field8(&rfcsr, RFCSR2_RESCAL_EN, 0); -++ rt2800_rfcsr_write(rt2x00dev, 2, rfcsr); -++ -++ rt2800_rfcsr_read(rt2x00dev, 1, &rfcsr); -++ rt2x00_set_field8(&rfcsr, RFCSR1_RF_BLOCK_EN, 1); -++ rt2800_rfcsr_write(rt2x00dev, 1, rfcsr); -++ -++ rt2800_rfcsr_read(rt2x00dev, 6, &rfcsr); -++ rfcsr |= 0xc0; -++ rt2800_rfcsr_write(rt2x00dev, 6, rfcsr); -++ -++ rt2800_rfcsr_read(rt2x00dev, 22, &rfcsr); -++ rfcsr |= 0x20; -++ rt2800_rfcsr_write(rt2x00dev, 22, rfcsr); -++ -++ rt2800_rfcsr_read(rt2x00dev, 46, &rfcsr); -++ rfcsr |= 0x20; -++ rt2800_rfcsr_write(rt2x00dev, 46, rfcsr); -++ -++ rt2800_rfcsr_read(rt2x00dev, 20, &rfcsr); -++ rfcsr &= ~0xee; -++ rt2800_rfcsr_write(rt2x00dev, 20, rfcsr); -++} -++ -+ static void rt2800_init_rfcsr_5390(struct rt2x00_dev *rt2x00dev) -+ { -+ rt2800_rf_init_calibration(rt2x00dev, 2); -+@@ -7064,6 +7202,9 @@ static void rt2800_init_rfcsr(struct rt2 -+ case RT3390: -+ rt2800_init_rfcsr_3390(rt2x00dev); -+ break; -++ case RT3883: -++ rt2800_init_rfcsr_3883(rt2x00dev); -++ break; -+ case RT3572: -+ rt2800_init_rfcsr_3572(rt2x00dev); -+ break; -diff --git a/package/mac80211/patches/600-0018-rt2x00-rt2800lib-use-the-extended-EEPROM-map-for-RT3.patch b/package/mac80211/patches/600-0018-rt2x00-rt2800lib-use-the-extended-EEPROM-map-for-RT3.patch -new file mode 100644 -index 0000000..57af961 ---- /dev/null -+++ b/package/mac80211/patches/600-0018-rt2x00-rt2800lib-use-the-extended-EEPROM-map-for-RT3.patch -@@ -0,0 +1,22 @@ -+From 86022438ffeb1b87dfcd018bf477fdbb43076691 Mon Sep 17 00:00:00 2001 -+From: Gabor Juhos -+Date: Wed, 8 May 2013 19:35:33 +0200 -+Subject: [PATCH] rt2x00: rt2800lib: use the extended EEPROM map for RT3883 -+ -+Signed-off-by: Gabor Juhos -+--- -+ drivers/net/wireless/rt2x00/rt2800lib.c | 3 ++- -+ 1 file changed, 2 insertions(+), 1 deletion(-) -+ -+--- a/drivers/net/wireless/rt2x00/rt2800lib.c -++++ b/drivers/net/wireless/rt2x00/rt2800lib.c -+@@ -342,7 +342,8 @@ static unsigned int rt2800_eeprom_word_i -+ wiphy_name(rt2x00dev->hw->wiphy), word)) -+ return 0; -+ -+- if (rt2x00_rt(rt2x00dev, RT3593)) -++ if (rt2x00_rt(rt2x00dev, RT3593) || -++ rt2x00_rt(rt2x00dev, RT3883)) -+ map = rt2800_eeprom_map_ext; -+ else -+ map = rt2800_eeprom_map; -diff --git a/package/mac80211/patches/600-0019-rt2x00-rt2800lib-force-rf-type-to-RF3853-on-RT3883.patch b/package/mac80211/patches/600-0019-rt2x00-rt2800lib-force-rf-type-to-RF3853-on-RT3883.patch -new file mode 100644 -index 0000000..50fa94f ---- /dev/null -+++ b/package/mac80211/patches/600-0019-rt2x00-rt2800lib-force-rf-type-to-RF3853-on-RT3883.patch -@@ -0,0 +1,21 @@ -+From 4cf5403f02fa65dc2207f61d223cffa9ae50e907 Mon Sep 17 00:00:00 2001 -+From: Gabor Juhos -+Date: Thu, 1 Aug 2013 14:48:21 +0200 -+Subject: [PATCH] rt2x00: rt2800lib: force rf type to RF3853 on RT3883 -+ -+Signed-off-by: Gabor Juhos -+--- -+ drivers/net/wireless/rt2x00/rt2800lib.c | 2 ++ -+ 1 file changed, 2 insertions(+) -+ -+--- a/drivers/net/wireless/rt2x00/rt2800lib.c -++++ b/drivers/net/wireless/rt2x00/rt2800lib.c -+@@ -7601,6 +7601,8 @@ static int rt2800_init_eeprom(struct rt2 -+ rt2x00_rt(rt2x00dev, RT5390) || -+ rt2x00_rt(rt2x00dev, RT5392)) -+ rt2800_eeprom_read(rt2x00dev, EEPROM_CHIP_ID, &rf); -++ else if (rt2x00_rt(rt2x00dev, RT3883)) -++ rf = RF3853; -+ else -+ rf = rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RF_TYPE); -+ -diff --git a/package/mac80211/patches/600-0020-rt2x00-rt2800lib-add-channel-configuration-code-for-.patch b/package/mac80211/patches/600-0020-rt2x00-rt2800lib-add-channel-configuration-code-for-.patch -new file mode 100644 -index 0000000..e717baa ---- /dev/null -+++ b/package/mac80211/patches/600-0020-rt2x00-rt2800lib-add-channel-configuration-code-for-.patch -@@ -0,0 +1,136 @@ -+From 269f19c848a2380db03a3f207cafb88e28d71c53 Mon Sep 17 00:00:00 2001 -+From: Gabor Juhos -+Date: Sun, 24 Mar 2013 19:26:28 +0100 -+Subject: [PATCH] rt2x00: rt2800lib: add channel configuration code for RT3883 -+ -+Signed-off-by: Gabor Juhos -+--- -+ drivers/net/wireless/rt2x00/rt2800lib.c | 72 +++++++++++++++++++++++++++++-- -+ 1 file changed, 69 insertions(+), 3 deletions(-) -+ -+--- a/drivers/net/wireless/rt2x00/rt2800lib.c -++++ b/drivers/net/wireless/rt2x00/rt2800lib.c -+@@ -3429,6 +3429,36 @@ static char rt2800_txpower_to_dev(struct -+ return clamp_t(char, txpower, MIN_A_TXPOWER, MAX_A_TXPOWER); -+ } -+ -++static void rt3883_bbp_adjust(struct rt2x00_dev *rt2x00dev, -++ struct rf_channel *rf) -++{ -++ u8 bbp; -++ -++ bbp = (rf->channel > 14) ? 0x48 : 0x38; -++ rt2800_bbp_write_with_rx_chain(rt2x00dev, 66, bbp); -++ -++ rt2800_bbp_write(rt2x00dev, 69, 0x12); -++ -++ if (rf->channel <= 14) { -++ rt2800_bbp_write(rt2x00dev, 70, 0x0a); -++ } else { -++ /* Disable CCK packet detection */ -++ rt2800_bbp_write(rt2x00dev, 70, 0x00); -++ } -++ -++ rt2800_bbp_write(rt2x00dev, 73, 0x10); -++ -++ if (rf->channel > 14) { -++ rt2800_bbp_write(rt2x00dev, 62, 0x1d); -++ rt2800_bbp_write(rt2x00dev, 63, 0x1d); -++ rt2800_bbp_write(rt2x00dev, 64, 0x1d); -++ } else { -++ rt2800_bbp_write(rt2x00dev, 62, 0x2d); -++ rt2800_bbp_write(rt2x00dev, 63, 0x2d); -++ rt2800_bbp_write(rt2x00dev, 64, 0x2d); -++ } -++} -++ -+ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, -+ struct ieee80211_conf *conf, -+ struct rf_channel *rf, -+@@ -3447,6 +3477,12 @@ static void rt2800_config_channel(struct -+ rt2800_txpower_to_dev(rt2x00dev, rf->channel, -+ info->default_power3); -+ -++ switch (rt2x00dev->chip.rt) { -++ case RT3883: -++ rt3883_bbp_adjust(rt2x00dev, rf); -++ break; -++ } -++ -+ switch (rt2x00dev->chip.rf) { -+ case RF2020: -+ case RF3020: -+@@ -3528,6 +3564,15 @@ static void rt2800_config_channel(struct -+ rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain); -+ rt2800_bbp_write(rt2x00dev, 64, 0x37 - rt2x00dev->lna_gain); -+ rt2800_bbp_write(rt2x00dev, 77, 0x98); -++ } else if (rt2x00_rt(rt2x00dev, RT3883)) { -++ 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 (rt2x00dev->default_ant.rx_chain_num > 1) -++ rt2800_bbp_write(rt2x00dev, 86, 0x46); -++ else -++ rt2800_bbp_write(rt2x00dev, 86, 0); -+ } else { -+ rt2800_bbp_write(rt2x00dev, 62, 0x37 - rt2x00dev->lna_gain); -+ rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain); -+@@ -3540,6 +3585,7 @@ static void rt2800_config_channel(struct -+ !rt2x00_rt(rt2x00dev, RT5392)) { -+ if (rt2x00_has_cap_external_lna_bg(rt2x00dev)) { -+ rt2800_bbp_write(rt2x00dev, 82, 0x62); -++ rt2800_bbp_write(rt2x00dev, 82, 0x62); -+ rt2800_bbp_write(rt2x00dev, 75, 0x46); -+ } else { -+ if (rt2x00_rt(rt2x00dev, RT3593)) -+@@ -3548,19 +3594,22 @@ static void rt2800_config_channel(struct -+ rt2800_bbp_write(rt2x00dev, 82, 0x84); -+ rt2800_bbp_write(rt2x00dev, 75, 0x50); -+ } -+- if (rt2x00_rt(rt2x00dev, RT3593)) -++ if (rt2x00_rt(rt2x00dev, RT3593) || -++ rt2x00_rt(rt2x00dev, RT3883)) -+ rt2800_bbp_write(rt2x00dev, 83, 0x8a); -+ } -+ -+ } else { -+ if (rt2x00_rt(rt2x00dev, RT3572)) -+ rt2800_bbp_write(rt2x00dev, 82, 0x94); -+- else if (rt2x00_rt(rt2x00dev, RT3593)) -++ else if (rt2x00_rt(rt2x00dev, RT3593) || -++ rt2x00_rt(rt2x00dev, RT3883)) -+ rt2800_bbp_write(rt2x00dev, 82, 0x82); -+ else -+ rt2800_bbp_write(rt2x00dev, 82, 0xf2); -+ -+- if (rt2x00_rt(rt2x00dev, RT3593)) -++ if (rt2x00_rt(rt2x00dev, RT3593) || -++ rt2x00_rt(rt2x00dev, RT3883)) -+ rt2800_bbp_write(rt2x00dev, 83, 0x9a); -+ -+ if (rt2x00_has_cap_external_lna_a(rt2x00dev)) -+@@ -3685,6 +3734,23 @@ static void rt2800_config_channel(struct -+ usleep_range(1000, 1500); -+ } -+ -++ if (rt2x00_rt(rt2x00dev, RT3883)) { -++ if (!conf_is_ht40(conf)) -++ rt2800_bbp_write(rt2x00dev, 105, 0x34); -++ else -++ rt2800_bbp_write(rt2x00dev, 105, 0x04); -++ -++ /* AGC init */ -++ if (rf->channel <= 14) -++ reg = 0x2e + rt2x00dev->lna_gain; -++ else -++ reg = 0x20 + ((rt2x00dev->lna_gain * 5) / 3); -++ -++ rt2800_bbp_write_with_rx_chain(rt2x00dev, 66, reg); -++ -++ usleep_range(1000, 1500); -++ } -++ -+ if (rt2x00_rt(rt2x00dev, RT5592)) { -+ rt2800_bbp_write(rt2x00dev, 195, 141); -+ rt2800_bbp_write(rt2x00dev, 196, conf_is_ht40(conf) ? 0x10 : 0x1a); -diff --git a/package/mac80211/patches/600-0021-rt2x00-rt2800lib-fix-txpower_to_dev-function-for-RT3.patch b/package/mac80211/patches/600-0021-rt2x00-rt2800lib-fix-txpower_to_dev-function-for-RT3.patch -new file mode 100644 -index 0000000..1773128 ---- /dev/null -+++ b/package/mac80211/patches/600-0021-rt2x00-rt2800lib-fix-txpower_to_dev-function-for-RT3.patch -@@ -0,0 +1,30 @@ -+From e37d93abaabe3ab72b0332a18092acc162307274 Mon Sep 17 00:00:00 2001 -+From: Gabor Juhos -+Date: Mon, 30 Sep 2013 13:57:26 +0200 -+Subject: [PATCH] rt2x00: rt2800lib: fix txpower_to_dev function for RT3883 -+ -+Signed-off-by: Gabor Juhos -+--- -+ drivers/net/wireless/rt2x00/rt2800lib.c | 6 ++++-- -+ 1 file changed, 4 insertions(+), 2 deletions(-) -+ -+--- a/drivers/net/wireless/rt2x00/rt2800lib.c -++++ b/drivers/net/wireless/rt2x00/rt2800lib.c -+@@ -3416,13 +3416,15 @@ static char rt2800_txpower_to_dev(struct -+ unsigned int channel, -+ char txpower) -+ { -+- if (rt2x00_rt(rt2x00dev, RT3593)) -++ if (rt2x00_rt(rt2x00dev, RT3593) || -++ rt2x00_rt(rt2x00dev, RT3883)) -+ txpower = rt2x00_get_field8(txpower, EEPROM_TXPOWER_ALC); -+ -+ if (channel <= 14) -+ return clamp_t(char, txpower, MIN_G_TXPOWER, MAX_G_TXPOWER); -+ -+- if (rt2x00_rt(rt2x00dev, RT3593)) -++ if (rt2x00_rt(rt2x00dev, RT3593) || -++ rt2x00_rt(rt2x00dev, RT3883)) -+ return clamp_t(char, txpower, MIN_A_TXPOWER_3593, -+ MAX_A_TXPOWER_3593); -+ else -diff --git a/package/mac80211/patches/600-0022-rt2x00-rt2800lib-use-correct-txpower-calculation-fun.patch b/package/mac80211/patches/600-0022-rt2x00-rt2800lib-use-correct-txpower-calculation-fun.patch -new file mode 100644 -index 0000000..4956373 ---- /dev/null -+++ b/package/mac80211/patches/600-0022-rt2x00-rt2800lib-use-correct-txpower-calculation-fun.patch -@@ -0,0 +1,23 @@ -+From c4d79e344bd580d85821390d49f92dced7d8e125 Mon Sep 17 00:00:00 2001 -+From: Gabor Juhos -+Date: Sun, 24 Mar 2013 19:26:29 +0100 -+Subject: [PATCH] rt2x00: rt2800lib: use correct txpower calculation function -+ for RT3883 -+ -+Signed-off-by: Gabor Juhos -+--- -+ drivers/net/wireless/rt2x00/rt2800lib.c | 3 ++- -+ 1 file changed, 2 insertions(+), 1 deletion(-) -+ -+--- a/drivers/net/wireless/rt2x00/rt2800lib.c -++++ b/drivers/net/wireless/rt2x00/rt2800lib.c -+@@ -4626,7 +4626,8 @@ static void rt2800_config_txpower(struct -+ struct ieee80211_channel *chan, -+ int power_level) -+ { -+- if (rt2x00_rt(rt2x00dev, RT3593)) -++ if (rt2x00_rt(rt2x00dev, RT3593) || -++ rt2x00_rt(rt2x00dev, RT3883)) -+ rt2800_config_txpower_rt3593(rt2x00dev, chan, power_level); -+ else -+ rt2800_config_txpower_rt28xx(rt2x00dev, chan, power_level); -diff --git a/package/mac80211/patches/600-0023-rt2x00-rt2800lib-hardcode-txmixer-gain-values-to-zer.patch b/package/mac80211/patches/600-0023-rt2x00-rt2800lib-hardcode-txmixer-gain-values-to-zer.patch -new file mode 100644 -index 0000000..a692fd8 ---- /dev/null -+++ b/package/mac80211/patches/600-0023-rt2x00-rt2800lib-hardcode-txmixer-gain-values-to-zer.patch -@@ -0,0 +1,33 @@ -+From caea0671cd8fd9ade4f5969cbe0ee545e94ae105 Mon Sep 17 00:00:00 2001 -+From: Gabor Juhos -+Date: Sat, 24 Aug 2013 11:49:55 +0200 -+Subject: [PATCH] rt2x00: rt2800lib: hardcode txmixer gain values to zero for -+ RT3883 -+ -+Signed-off-by: Gabor Juhos -+--- -+ drivers/net/wireless/rt2x00/rt2800lib.c | 6 ++++-- -+ 1 file changed, 4 insertions(+), 2 deletions(-) -+ -+--- a/drivers/net/wireless/rt2x00/rt2800lib.c -++++ b/drivers/net/wireless/rt2x00/rt2800lib.c -+@@ -7483,7 +7483,8 @@ static u8 rt2800_get_txmixer_gain_24g(st -+ { -+ u16 word; -+ -+- if (rt2x00_rt(rt2x00dev, RT3593)) -++ if (rt2x00_rt(rt2x00dev, RT3593) || -++ rt2x00_rt(rt2x00dev, RT3883)) -+ return 0; -+ -+ rt2800_eeprom_read(rt2x00dev, EEPROM_TXMIXER_GAIN_BG, &word); -+@@ -7497,7 +7498,8 @@ static u8 rt2800_get_txmixer_gain_5g(str -+ { -+ u16 word; -+ -+- if (rt2x00_rt(rt2x00dev, RT3593)) -++ if (rt2x00_rt(rt2x00dev, RT3593) || -++ rt2x00_rt(rt2x00dev, RT3883)) -+ return 0; -+ -+ rt2800_eeprom_read(rt2x00dev, EEPROM_TXMIXER_GAIN_A, &word); -diff --git a/package/mac80211/patches/600-0024-rt2x00-rt2800lib-use-correct-RT-XWI-size-for-RT3883.patch b/package/mac80211/patches/600-0024-rt2x00-rt2800lib-use-correct-RT-XWI-size-for-RT3883.patch -new file mode 100644 -index 0000000..53435aa ---- /dev/null -+++ b/package/mac80211/patches/600-0024-rt2x00-rt2800lib-use-correct-RT-XWI-size-for-RT3883.patch -@@ -0,0 +1,20 @@ -+From 11c40fb47c4a4dd6ad060c2ae127ced89ffb9fe1 Mon Sep 17 00:00:00 2001 -+From: Gabor Juhos -+Date: Thu, 18 Apr 2013 14:33:33 +0200 -+Subject: [PATCH] rt2x00: rt2800lib: use correct [RT]XWI size for RT3883 -+ -+Signed-off-by: Gabor Juhos -+--- -+ drivers/net/wireless/rt2x00/rt2800lib.c | 1 + -+ 1 file changed, 1 insertion(+) -+ -+--- a/drivers/net/wireless/rt2x00/rt2800lib.c -++++ b/drivers/net/wireless/rt2x00/rt2800lib.c -+@@ -558,6 +558,7 @@ void rt2800_get_txwi_rxwi_size(struct rt -+ { -+ switch (rt2x00dev->chip.rt) { -+ case RT3593: -++ case RT3883: -+ *txwi_size = TXWI_DESC_SIZE_4WORDS; -+ *rxwi_size = RXWI_DESC_SIZE_5WORDS; -+ break; -diff --git a/package/mac80211/patches/600-0025-rt2x00-rt2800lib-use-correct-beacon-base-for-RT3883.patch b/package/mac80211/patches/600-0025-rt2x00-rt2800lib-use-correct-beacon-base-for-RT3883.patch -new file mode 100644 -index 0000000..08f3f88 ---- /dev/null -+++ b/package/mac80211/patches/600-0025-rt2x00-rt2800lib-use-correct-beacon-base-for-RT3883.patch -@@ -0,0 +1,22 @@ -+From b403bdfa00665ce6b53583bdb837ffad0b91c09f Mon Sep 17 00:00:00 2001 -+From: Gabor Juhos -+Date: Sun, 24 Mar 2013 19:26:29 +0100 -+Subject: [PATCH] rt2x00: rt2800lib: use correct beacon base for RT3883 -+ -+Signed-off-by: Gabor Juhos -+--- -+ drivers/net/wireless/rt2x00/rt2800lib.c | 3 ++- -+ 1 file changed, 2 insertions(+), 1 deletion(-) -+ -+--- a/drivers/net/wireless/rt2x00/rt2800lib.c -++++ b/drivers/net/wireless/rt2x00/rt2800lib.c -+@@ -983,7 +983,8 @@ EXPORT_SYMBOL_GPL(rt2800_txdone_entry); -+ static unsigned int rt2800_hw_beacon_base(struct rt2x00_dev *rt2x00dev, -+ unsigned int index) -+ { -+- if (rt2x00_rt(rt2x00dev, RT3593)) -++ if (rt2x00_rt(rt2x00dev, RT3593) || -++ rt2x00_rt(rt2x00dev, RT3883)) -+ return HW_BEACON_BASE_HIGH(index); -+ -+ return HW_BEACON_BASE(index); -diff --git a/package/mac80211/patches/600-0026-rt2x00-rt2800lib-use-correct-beacon-count-for-RT3883.patch b/package/mac80211/patches/600-0026-rt2x00-rt2800lib-use-correct-beacon-count-for-RT3883.patch -new file mode 100644 -index 0000000..f8fe496 ---- /dev/null -+++ b/package/mac80211/patches/600-0026-rt2x00-rt2800lib-use-correct-beacon-count-for-RT3883.patch -@@ -0,0 +1,22 @@ -+From 74b7eaf75fc6eb86292056ef705e543f9cd6086b Mon Sep 17 00:00:00 2001 -+From: Gabor Juhos -+Date: Sun, 18 Aug 2013 09:57:58 +0200 -+Subject: [PATCH] rt2x00: rt2800lib: use correct beacon count for RT3883 -+ -+Signed-off-by: Gabor Juhos -+--- -+ drivers/net/wireless/rt2x00/rt2800lib.c | 3 ++- -+ 1 file changed, 2 insertions(+), 1 deletion(-) -+ -+--- a/drivers/net/wireless/rt2x00/rt2800lib.c -++++ b/drivers/net/wireless/rt2x00/rt2800lib.c -+@@ -8415,7 +8415,8 @@ int rt2800_probe_hw(struct rt2x00_dev *r -+ if (rt2x00_rt(rt2x00dev, RT3593)) -+ __set_bit(RT2800_HAS_HIGH_SHARED_MEM, &drv_data->rt2800_flags); -+ -+- if (rt2x00_rt(rt2x00dev, RT3593)) -++ if (rt2x00_rt(rt2x00dev, RT3593) || -++ rt2x00_rt(rt2x00dev, RT3883)) -+ drv_data->hw_beacon_count = 16; -+ else -+ drv_data->hw_beacon_count = 8; -diff --git a/package/mac80211/patches/600-0027-rt2x00-rt2800lib-fix-antenna-configuration-for-RT388.patch b/package/mac80211/patches/600-0027-rt2x00-rt2800lib-fix-antenna-configuration-for-RT388.patch -new file mode 100644 -index 0000000..22f7110 ---- /dev/null -+++ b/package/mac80211/patches/600-0027-rt2x00-rt2800lib-fix-antenna-configuration-for-RT388.patch -@@ -0,0 +1,22 @@ -+From fa5ad9c025610c22048add2f0ad03f62b6ca1e74 Mon Sep 17 00:00:00 2001 -+From: Gabor Juhos -+Date: Mon, 30 Sep 2013 16:53:33 +0200 -+Subject: [PATCH] rt2x00: rt2800lib: fix antenna configuration for RT3883 -+ -+Signed-off-by: Gabor Juhos -+--- -+ drivers/net/wireless/rt2x00/rt2800lib.c | 3 ++- -+ 1 file changed, 2 insertions(+), 1 deletion(-) -+ -+--- a/drivers/net/wireless/rt2x00/rt2800lib.c -++++ b/drivers/net/wireless/rt2x00/rt2800lib.c -+@@ -1961,7 +1961,8 @@ void rt2800_config_ant(struct rt2x00_dev -+ rt2800_bbp_write(rt2x00dev, 3, r3); -+ rt2800_bbp_write(rt2x00dev, 1, r1); -+ -+- if (rt2x00_rt(rt2x00dev, RT3593)) { -++ if (rt2x00_rt(rt2x00dev, RT3593) || -++ rt2x00_rt(rt2x00dev, RT3883)) { -+ if (ant->rx_chain_num == 1) -+ rt2800_bbp_write(rt2x00dev, 86, 0x00); -+ else -diff --git a/package/mac80211/patches/600-0028-rt2x00-rt2800lib-fix-LNA-gain-configuration-for-RT38.patch b/package/mac80211/patches/600-0028-rt2x00-rt2800lib-fix-LNA-gain-configuration-for-RT38.patch -new file mode 100644 -index 0000000..9945f38 ---- /dev/null -+++ b/package/mac80211/patches/600-0028-rt2x00-rt2800lib-fix-LNA-gain-configuration-for-RT38.patch -@@ -0,0 +1,32 @@ -+From 6d668fef3a1baa60bdd715ee062ddb6333d2647c Mon Sep 17 00:00:00 2001 -+From: Gabor Juhos -+Date: Mon, 30 Sep 2013 16:58:23 +0200 -+Subject: [PATCH] rt2x00: rt2800lib: fix LNA gain configuration for RT3883 -+ -+Signed-off-by: Gabor Juhos -+--- -+ drivers/net/wireless/rt2x00/rt2800lib.c | 6 ++++-- -+ 1 file changed, 4 insertions(+), 2 deletions(-) -+ -+--- a/drivers/net/wireless/rt2x00/rt2800lib.c -++++ b/drivers/net/wireless/rt2x00/rt2800lib.c -+@@ -1984,7 +1984,8 @@ static void rt2800_config_lna_gain(struc -+ rt2800_eeprom_read(rt2x00dev, EEPROM_LNA, &eeprom); -+ lna_gain = rt2x00_get_field16(eeprom, EEPROM_LNA_A0); -+ } else if (libconf->rf.channel <= 128) { -+- if (rt2x00_rt(rt2x00dev, RT3593)) { -++ if (rt2x00_rt(rt2x00dev, RT3593) || -++ rt2x00_rt(rt2x00dev, RT3883)) { -+ rt2800_eeprom_read(rt2x00dev, EEPROM_EXT_LNA2, &eeprom); -+ lna_gain = rt2x00_get_field16(eeprom, -+ EEPROM_EXT_LNA2_A1); -+@@ -1994,7 +1995,8 @@ static void rt2800_config_lna_gain(struc -+ EEPROM_RSSI_BG2_LNA_A1); -+ } -+ } else { -+- if (rt2x00_rt(rt2x00dev, RT3593)) { -++ if (rt2x00_rt(rt2x00dev, RT3593) || -++ rt2x00_rt(rt2x00dev, RT3883)) { -+ rt2800_eeprom_read(rt2x00dev, EEPROM_EXT_LNA2, &eeprom); -+ lna_gain = rt2x00_get_field16(eeprom, -+ EEPROM_EXT_LNA2_A2); -diff --git a/package/mac80211/patches/600-0029-rt2x00-rt2800lib-fix-VGC-setup-for-RT3883.patch b/package/mac80211/patches/600-0029-rt2x00-rt2800lib-fix-VGC-setup-for-RT3883.patch -new file mode 100644 -index 0000000..80b3668 ---- /dev/null -+++ b/package/mac80211/patches/600-0029-rt2x00-rt2800lib-fix-VGC-setup-for-RT3883.patch -@@ -0,0 +1,44 @@ -+From c49b2d829aa1c816a46a577cdec6d2ff14d9f06e Mon Sep 17 00:00:00 2001 -+From: Gabor Juhos -+Date: Tue, 1 Oct 2013 15:40:08 +0200 -+Subject: [PATCH] rt2x00: rt2800lib: fix VGC setup for RT3883 -+ -+Signed-off-by: Gabor Juhos -+--- -+ drivers/net/wireless/rt2x00/rt2800lib.c | 11 +++++++++-- -+ 1 file changed, 9 insertions(+), 2 deletions(-) -+ -+--- a/drivers/net/wireless/rt2x00/rt2800lib.c -++++ b/drivers/net/wireless/rt2x00/rt2800lib.c -+@@ -4825,7 +4825,8 @@ static u8 rt2800_get_default_vgc(struct -+ else -+ vgc = 0x2e + rt2x00dev->lna_gain; -+ } else { /* 5GHZ band */ -+- if (rt2x00_rt(rt2x00dev, RT3593)) -++ if (rt2x00_rt(rt2x00dev, RT3593) || -++ rt2x00_rt(rt2x00dev, RT3883)) -+ vgc = 0x20 + (rt2x00dev->lna_gain * 5) / 3; -+ else if (rt2x00_rt(rt2x00dev, RT5592)) -+ vgc = 0x24 + (2 * rt2x00dev->lna_gain); -+@@ -4845,7 +4846,8 @@ static inline void rt2800_set_vgc(struct -+ { -+ if (qual->vgc_level != vgc_level) { -+ if (rt2x00_rt(rt2x00dev, RT3572) || -+- rt2x00_rt(rt2x00dev, RT3593)) { -++ rt2x00_rt(rt2x00dev, RT3593) || -++ rt2x00_rt(rt2x00dev, RT3883)) { -+ rt2800_bbp_write_with_rx_chain(rt2x00dev, 66, -+ vgc_level); -+ } else if (rt2x00_rt(rt2x00dev, RT5592)) { -+@@ -4892,6 +4894,11 @@ void rt2800_link_tuner(struct rt2x00_dev -+ } -+ break; -+ -++ case RT3883: -++ if (qual->rssi > -65) -++ vgc += 0x10; -++ break; -++ -+ case RT5592: -+ if (qual->rssi > -65) -+ vgc += 0x20; -diff --git a/package/mac80211/patches/600-0030-rt2x00-rt2800lib-fix-EEPROM-LNA-validation-for-RT388.patch b/package/mac80211/patches/600-0030-rt2x00-rt2800lib-fix-EEPROM-LNA-validation-for-RT388.patch -new file mode 100644 -index 0000000..424acff ---- /dev/null -+++ b/package/mac80211/patches/600-0030-rt2x00-rt2800lib-fix-EEPROM-LNA-validation-for-RT388.patch -@@ -0,0 +1,42 @@ -+From 1616650aea676541d4dc8adc6f4219856d193c8b Mon Sep 17 00:00:00 2001 -+From: Gabor Juhos -+Date: Tue, 1 Oct 2013 17:27:57 +0200 -+Subject: [PATCH] rt2x00: rt2800lib: fix EEPROM LNA validation for RT3883 -+ -+Signed-off-by: Gabor Juhos -+--- -+ drivers/net/wireless/rt2x00/rt2800lib.c | 9 ++++++--- -+ 1 file changed, 6 insertions(+), 3 deletions(-) -+ -+--- a/drivers/net/wireless/rt2x00/rt2800lib.c -++++ b/drivers/net/wireless/rt2x00/rt2800lib.c -+@@ -7620,7 +7620,8 @@ static int rt2800_validate_eeprom(struct -+ rt2800_eeprom_read(rt2x00dev, EEPROM_RSSI_BG2, &word); -+ if (abs(rt2x00_get_field16(word, EEPROM_RSSI_BG2_OFFSET2)) > 10) -+ rt2x00_set_field16(&word, EEPROM_RSSI_BG2_OFFSET2, 0); -+- if (!rt2x00_rt(rt2x00dev, RT3593)) { -++ if (!rt2x00_rt(rt2x00dev, RT3593) && -++ !rt2x00_rt(rt2x00dev, RT3883)) { -+ if (rt2x00_get_field16(word, EEPROM_RSSI_BG2_LNA_A1) == 0x00 || -+ rt2x00_get_field16(word, EEPROM_RSSI_BG2_LNA_A1) == 0xff) -+ rt2x00_set_field16(&word, EEPROM_RSSI_BG2_LNA_A1, -+@@ -7640,7 +7641,8 @@ static int rt2800_validate_eeprom(struct -+ rt2800_eeprom_read(rt2x00dev, EEPROM_RSSI_A2, &word); -+ if (abs(rt2x00_get_field16(word, EEPROM_RSSI_A2_OFFSET2)) > 10) -+ rt2x00_set_field16(&word, EEPROM_RSSI_A2_OFFSET2, 0); -+- if (!rt2x00_rt(rt2x00dev, RT3593)) { -++ if (!rt2x00_rt(rt2x00dev, RT3593) && -++ !rt2x00_rt(rt2x00dev, RT3883)) { -+ if (rt2x00_get_field16(word, EEPROM_RSSI_A2_LNA_A2) == 0x00 || -+ rt2x00_get_field16(word, EEPROM_RSSI_A2_LNA_A2) == 0xff) -+ rt2x00_set_field16(&word, EEPROM_RSSI_A2_LNA_A2, -+@@ -7648,7 +7650,8 @@ static int rt2800_validate_eeprom(struct -+ } -+ rt2800_eeprom_write(rt2x00dev, EEPROM_RSSI_A2, word); -+ -+- if (rt2x00_rt(rt2x00dev, RT3593)) { -++ if (rt2x00_rt(rt2x00dev, RT3593) || -++ rt2x00_rt(rt2x00dev, RT3883)) { -+ rt2800_eeprom_read(rt2x00dev, EEPROM_EXT_LNA2, &word); -+ if (rt2x00_get_field16(word, EEPROM_EXT_LNA2_A1) == 0x00 || -+ rt2x00_get_field16(word, EEPROM_EXT_LNA2_A1) == 0xff) -diff --git a/package/mac80211/patches/600-0031-rt2x00-rt2800lib-fix-txpower-compensation-for-RT3883.patch b/package/mac80211/patches/600-0031-rt2x00-rt2800lib-fix-txpower-compensation-for-RT3883.patch -new file mode 100644 -index 0000000..00be526 ---- /dev/null -+++ b/package/mac80211/patches/600-0031-rt2x00-rt2800lib-fix-txpower-compensation-for-RT3883.patch -@@ -0,0 +1,22 @@ -+From e3871034a0e7c8a95152dc3eafbcc4535398cbdc Mon Sep 17 00:00:00 2001 -+From: Gabor Juhos -+Date: Wed, 2 Oct 2013 10:11:59 +0200 -+Subject: [PATCH] rt2x00: rt2800lib: fix txpower compensation for RT3883 -+ -+Signed-off-by: Gabor Juhos -+--- -+ drivers/net/wireless/rt2x00/rt2800lib.c | 3 +++ -+ 1 file changed, 3 insertions(+) -+ -+--- a/drivers/net/wireless/rt2x00/rt2800lib.c -++++ b/drivers/net/wireless/rt2x00/rt2800lib.c -+@@ -4003,6 +4003,9 @@ static u8 rt2800_compensate_txpower(stru -+ if (rt2x00_rt(rt2x00dev, RT3593)) -+ return min_t(u8, txpower, 0xc); -+ -++ if (rt2x00_rt(rt2x00dev, RT3883)) -++ return min_t(u8, txpower, 0xf); -++ -+ if (rt2x00_has_cap_power_limit(rt2x00dev)) { -+ /* -+ * Check if eirp txpower exceed txpower_limit. -diff --git a/package/mac80211/patches/600-0032-rt2x00-rt2800lib-enable-RT2800_HAS_HIGH_SHARED_MEM-f.patch b/package/mac80211/patches/600-0032-rt2x00-rt2800lib-enable-RT2800_HAS_HIGH_SHARED_MEM-f.patch -new file mode 100644 -index 0000000..7c4c1ab ---- /dev/null -+++ b/package/mac80211/patches/600-0032-rt2x00-rt2800lib-enable-RT2800_HAS_HIGH_SHARED_MEM-f.patch -@@ -0,0 +1,23 @@ -+From f6734ec72da936989a8ce4186b3ede28fbc47836 Mon Sep 17 00:00:00 2001 -+From: Gabor Juhos -+Date: Sun, 18 Aug 2013 21:57:34 +0200 -+Subject: [PATCH] rt2x00: rt2800lib: enable RT2800_HAS_HIGH_SHARED_MEM for -+ RT3883 -+ -+Signed-off-by: Gabor Juhos -+--- -+ drivers/net/wireless/rt2x00/rt2800lib.c | 3 ++- -+ 1 file changed, 2 insertions(+), 1 deletion(-) -+ -+--- a/drivers/net/wireless/rt2x00/rt2800lib.c -++++ b/drivers/net/wireless/rt2x00/rt2800lib.c -+@@ -8428,7 +8428,8 @@ int rt2800_probe_hw(struct rt2x00_dev *r -+ if (retval) -+ return retval; -+ -+- if (rt2x00_rt(rt2x00dev, RT3593)) -++ if (rt2x00_rt(rt2x00dev, RT3593) || -++ rt2x00_rt(rt2x00dev, RT3883)) -+ __set_bit(RT2800_HAS_HIGH_SHARED_MEM, &drv_data->rt2800_flags); -+ -+ if (rt2x00_rt(rt2x00dev, RT3593) || -diff --git a/package/mac80211/patches/600-0033-rt2x00-rt2800lib-use-high-memory-for-beacons-on-RT38.patch b/package/mac80211/patches/600-0033-rt2x00-rt2800lib-use-high-memory-for-beacons-on-RT38.patch -new file mode 100644 -index 0000000..dc06e6a ---- /dev/null -+++ b/package/mac80211/patches/600-0033-rt2x00-rt2800lib-use-high-memory-for-beacons-on-RT38.patch -@@ -0,0 +1,22 @@ -+From f1acfc2f397e86548ae1b479c198d4bef57050f6 Mon Sep 17 00:00:00 2001 -+From: Gabor Juhos -+Date: Sun, 29 Sep 2013 18:10:34 +0200 -+Subject: [PATCH] rt2x00: rt2800lib: use high memory for beacons on RT3883 -+ -+Signed-off-by: Gabor Juhos -+--- -+ drivers/net/wireless/rt2x00/rt2800lib.c | 3 ++- -+ 1 file changed, 2 insertions(+), 1 deletion(-) -+ -+--- a/drivers/net/wireless/rt2x00/rt2800lib.c -++++ b/drivers/net/wireless/rt2x00/rt2800lib.c -+@@ -97,7 +97,8 @@ static inline void rt2800_shared_mem_sel -+ -+ static inline bool rt2800_beacon_uses_high_mem(struct rt2x00_dev *rt2x00dev) -+ { -+- if (rt2x00_rt(rt2x00dev, RT3593)) -++ if (rt2x00_rt(rt2x00dev, RT3593) || -++ rt2x00_rt(rt2x00dev, RT3883)) -+ return true; -+ -+ return false; -diff --git a/package/mac80211/patches/600-0034-rt2x00-rt2800mmio-add-a-workaround-for-spurious-TX_F.patch b/package/mac80211/patches/600-0034-rt2x00-rt2800mmio-add-a-workaround-for-spurious-TX_F.patch -new file mode 100644 -index 0000000..79334dd ---- /dev/null -+++ b/package/mac80211/patches/600-0034-rt2x00-rt2800mmio-add-a-workaround-for-spurious-TX_F.patch -@@ -0,0 +1,136 @@ -+From 5e67d4f8a46d19748b501c2ef86de3f50d3cfd51 Mon Sep 17 00:00:00 2001 -+From: Gabor Juhos -+Date: Sun, 24 Mar 2013 19:26:27 +0100 -+Subject: [PATCH] rt2x00: rt2800mmio: add a workaround for spurious -+ TX_FIFO_STATUS interrupts -+ -+Signed-off-by: Gabor Juhos -+--- -+ drivers/net/wireless/rt2x00/rt2800mmio.c | 72 +++++++++++++++++++++++++----- -+ drivers/net/wireless/rt2x00/rt2x00.h | 5 +++ -+ 2 files changed, 65 insertions(+), 12 deletions(-) -+ -+--- a/drivers/net/wireless/rt2x00/rt2800mmio.c -++++ b/drivers/net/wireless/rt2x00/rt2800mmio.c -+@@ -415,9 +415,9 @@ void rt2800mmio_autowake_tasklet(unsigne -+ } -+ EXPORT_SYMBOL_GPL(rt2800mmio_autowake_tasklet); -+ -+-static void rt2800mmio_txstatus_interrupt(struct rt2x00_dev *rt2x00dev) -++static void rt2800mmio_txstatus_interrupt(struct rt2x00_dev *rt2x00dev, -++ u32 status) -+ { -+- u32 status; -+ int i; -+ -+ /* -+@@ -438,29 +438,77 @@ static void rt2800mmio_txstatus_interrup -+ * Since we have only one producer and one consumer we don't -+ * need to lock the kfifo. -+ */ -+- for (i = 0; i < rt2x00dev->tx->limit; i++) { -+- rt2x00mmio_register_read(rt2x00dev, TX_STA_FIFO, &status); -+- -+- if (!rt2x00_get_field32(status, TX_STA_FIFO_VALID)) -+- break; -+- -++ i = 0; -++ do { -+ if (!kfifo_put(&rt2x00dev->txstatus_fifo, status)) { -+- rt2x00_warn(rt2x00dev, "TX status FIFO overrun, drop tx status report\n"); -++ rt2x00_warn(rt2x00dev, -++ "TX status FIFO overrun, drop TX status report\n"); -+ break; -+ } -+- } -++ -++ if (++i >= rt2x00dev->tx->limit) -++ break; -++ -++ rt2x00mmio_register_read(rt2x00dev, TX_STA_FIFO, &status); -++ } while (rt2x00_get_field32(status, TX_STA_FIFO_VALID)); -+ -+ /* Schedule the tasklet for processing the tx status. */ -+ tasklet_schedule(&rt2x00dev->txstatus_tasklet); -+ } -+ -++#define RT2800MMIO_TXSTATUS_IRQ_MAX_RETRIES 4 -++ -++static bool rt2800mmio_txstatus_is_spurious(struct rt2x00_dev *rt2x00dev, -++ u32 txstatus) -++{ -++ if (likely(rt2x00_get_field32(txstatus, TX_STA_FIFO_VALID))) { -++ rt2x00dev->txstatus_irq_retries = 0; -++ return false; -++ } -++ -++ rt2x00dev->txstatus_irq_retries++; -++ -++ /* Ensure that we don't go into an infinite IRQ loop. */ -++ if (rt2x00dev->txstatus_irq_retries >= -++ RT2800MMIO_TXSTATUS_IRQ_MAX_RETRIES) { -++ rt2x00_warn(rt2x00dev, -++ "%u spurious TX_FIFO_STATUS interrupt(s)\n", -++ rt2x00dev->txstatus_irq_retries); -++ rt2x00dev->txstatus_irq_retries = 0; -++ return false; -++ } -++ -++ return true; -++} -++ -+ irqreturn_t rt2800mmio_interrupt(int irq, void *dev_instance) -+ { -+ struct rt2x00_dev *rt2x00dev = dev_instance; -+ u32 reg, mask; -++ u32 txstatus = 0; -+ -+- /* Read status and ACK all interrupts */ -++ /* Read status */ -+ rt2x00mmio_register_read(rt2x00dev, INT_SOURCE_CSR, ®); -++ -++ if (rt2x00_get_field32(reg, INT_SOURCE_CSR_TX_FIFO_STATUS)) { -++ /* Due to unknown reason the hardware generates a -++ * TX_FIFO_STATUS interrupt before the TX_STA_FIFO -++ * register contain valid data. Read the TX status -++ * here to see if we have to process the actual -++ * request. -++ */ -++ rt2x00mmio_register_read(rt2x00dev, TX_STA_FIFO, &txstatus); -++ if (rt2800mmio_txstatus_is_spurious(rt2x00dev, txstatus)) { -++ /* Remove the TX_FIFO_STATUS bit so it won't be -++ * processed in this turn. The hardware will -++ * generate another IRQ for us. -++ */ -++ rt2x00_set_field32(®, -++ INT_SOURCE_CSR_TX_FIFO_STATUS, 0); -++ } -++ } -++ -++ /* ACK interrupts */ -+ rt2x00mmio_register_write(rt2x00dev, INT_SOURCE_CSR, reg); -+ -+ if (!reg) -+@@ -477,7 +525,7 @@ irqreturn_t rt2800mmio_interrupt(int irq -+ mask = ~reg; -+ -+ if (rt2x00_get_field32(reg, INT_SOURCE_CSR_TX_FIFO_STATUS)) { -+- rt2800mmio_txstatus_interrupt(rt2x00dev); -++ rt2800mmio_txstatus_interrupt(rt2x00dev, txstatus); -+ /* -+ * Never disable the TX_FIFO_STATUS interrupt. -+ */ -+--- a/drivers/net/wireless/rt2x00/rt2x00.h -++++ b/drivers/net/wireless/rt2x00/rt2x00.h -+@@ -986,6 +986,11 @@ struct rt2x00_dev { -+ int rf_channel; -+ -+ /* -++ * Counter for tx status irq retries (rt2800pci). -++ */ -++ unsigned int txstatus_irq_retries; -++ -++ /* -+ * Protect the interrupt mask register. -+ */ -+ spinlock_t irqmask_lock; -diff --git a/package/mac80211/patches/603-rt2x00-introduce-rt2x00eeprom.patch b/package/mac80211/patches/603-rt2x00-introduce-rt2x00eeprom.patch -index 2bbc6f1..e5ba10e 100644 ---- a/package/mac80211/patches/603-rt2x00-introduce-rt2x00eeprom.patch -+++ b/package/mac80211/patches/603-rt2x00-introduce-rt2x00eeprom.patch -@@ -1,6 +1,6 @@ - --- a/.local-symbols - +++ b/.local-symbols --@@ -279,6 +279,7 @@ RT2X00_LIB_FIRMWARE= -+@@ -281,6 +281,7 @@ RT2X00_LIB_FIRMWARE= - RT2X00_LIB_CRYPTO= - RT2X00_LIB_LEDS= - RT2X00_LIB_DEBUGFS= -@@ -48,16 +48,16 @@ - obj-$(CPTCFG_RT2X00_LIB_MMIO) += rt2x00mmio.o - --- a/drivers/net/wireless/rt2x00/rt2800lib.h - +++ b/drivers/net/wireless/rt2x00/rt2800lib.h --@@ -20,6 +20,8 @@ -- #ifndef RT2800LIB_H -- #define RT2800LIB_H -+@@ -43,6 +43,8 @@ struct rt2800_drv_data { -+ } shmem_lock; -+ }; - - +#include "rt2800.h" - + - struct rt2800_ops { - void (*register_read)(struct rt2x00_dev *rt2x00dev, - const unsigned int offset, u32 *value); --@@ -119,6 +121,15 @@ static inline int rt2800_read_eeprom(str -+@@ -176,6 +178,15 @@ static inline int rt2800_read_eeprom(str - { - const struct rt2800_ops *rt2800ops = rt2x00dev->ops->drv; - -@@ -75,7 +75,7 @@ - - --- a/drivers/net/wireless/rt2x00/rt2800soc.c - +++ b/drivers/net/wireless/rt2x00/rt2800soc.c --@@ -95,19 +95,6 @@ static int rt2800soc_set_device_state(st -+@@ -102,19 +102,6 @@ static int rt2800soc_set_device_state(st - return retval; - } - -@@ -95,7 +95,7 @@ - /* Firmware functions */ - static char *rt2800soc_get_firmware_name(struct rt2x00_dev *rt2x00dev) - { --@@ -171,7 +158,6 @@ static const struct rt2800_ops rt2800soc -+@@ -178,7 +165,6 @@ static const struct rt2800_ops rt2800soc - .register_multiread = rt2x00mmio_register_multiread, - .register_multiwrite = rt2x00mmio_register_multiwrite, - .regbusy_read = rt2x00mmio_regbusy_read, -@@ -127,7 +127,7 @@ - DECLARE_KFIFO_PTR(txstatus_fifo, u32); - --- a/drivers/net/wireless/rt2x00/rt2x00dev.c - +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c --@@ -1324,6 +1324,10 @@ int rt2x00lib_probe_dev(struct rt2x00_de -+@@ -1327,6 +1327,10 @@ int rt2x00lib_probe_dev(struct rt2x00_de - INIT_DELAYED_WORK(&rt2x00dev->autowakeup_work, rt2x00lib_autowakeup); - INIT_WORK(&rt2x00dev->sleep_work, rt2x00lib_sleep); - -@@ -138,7 +138,7 @@ - /* - * Let the driver probe the device to detect the capabilities. - */ --@@ -1454,6 +1458,11 @@ void rt2x00lib_remove_dev(struct rt2x00_ -+@@ -1457,6 +1461,11 @@ void rt2x00lib_remove_dev(struct rt2x00_ - */ - if (rt2x00dev->drv_data) - kfree(rt2x00dev->drv_data); -diff --git a/package/mac80211/patches/607-rt2x00-allow_disabling_bands_through_platform_data.patch b/package/mac80211/patches/607-rt2x00-allow_disabling_bands_through_platform_data.patch -index 4116735..70f7b78 100644 ---- a/package/mac80211/patches/607-rt2x00-allow_disabling_bands_through_platform_data.patch -+++ b/package/mac80211/patches/607-rt2x00-allow_disabling_bands_through_platform_data.patch -@@ -12,7 +12,7 @@ - #endif /* _RT2X00_PLATFORM_H */ - --- a/drivers/net/wireless/rt2x00/rt2x00dev.c - +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c --@@ -937,6 +937,22 @@ static int rt2x00lib_probe_hw_modes(stru -+@@ -940,6 +940,22 @@ static int rt2x00lib_probe_hw_modes(stru - unsigned int num_rates; - unsigned int i; - -diff --git a/package/mac80211/patches/608-add_platform_data_mac_addr.patch b/package/mac80211/patches/608-add_platform_data_mac_addr.patch -index a910cc3..4c2a8b8 100644 ---- a/package/mac80211/patches/608-add_platform_data_mac_addr.patch -+++ b/package/mac80211/patches/608-add_platform_data_mac_addr.patch -@@ -10,7 +10,7 @@ - int disable_5ghz; - --- a/drivers/net/wireless/rt2x00/rt2x00dev.c - +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c --@@ -928,6 +928,18 @@ static void rt2x00lib_rate(struct ieee80 -+@@ -931,6 +931,18 @@ static void rt2x00lib_rate(struct ieee80 - entry->flags |= IEEE80211_RATE_SHORT_PREAMBLE; - } - -@@ -31,7 +31,7 @@ - { - --- a/drivers/net/wireless/rt2x00/rt2x00.h - +++ b/drivers/net/wireless/rt2x00/rt2x00.h --@@ -1401,6 +1401,7 @@ static inline void rt2x00debug_dump_fram -+@@ -1406,6 +1406,7 @@ static inline void rt2x00debug_dump_fram - */ - u32 rt2x00lib_get_bssidx(struct rt2x00_dev *rt2x00dev, - struct ieee80211_vif *vif); -diff --git a/package/mac80211/patches/610-rt2x00-fix-rt3352-ext-pa.patch b/package/mac80211/patches/610-rt2x00-fix-rt3352-ext-pa.patch -index 83fbcd0..010a9e2 100644 ---- a/package/mac80211/patches/610-rt2x00-fix-rt3352-ext-pa.patch -+++ b/package/mac80211/patches/610-rt2x00-fix-rt3352-ext-pa.patch -@@ -1,14 +1,15 @@ - --- a/drivers/net/wireless/rt2x00/rt2800lib.c - +++ b/drivers/net/wireless/rt2x00/rt2800lib.c --@@ -3176,11 +3176,17 @@ static void rt2800_config_channel(struct -+@@ -3550,11 +3550,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, 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, 27, 0x0); - rt2800_bbp_write(rt2x00dev, 66, 0x26 + rt2x00dev->lna_gain); - rt2800_bbp_write(rt2x00dev, 27, 0x20); -@@ -18,22 +19,7 @@ - } else if (rt2x00_rt(rt2x00dev, RT3593)) { - if (rf->channel > 14) { - /* Disable CCK Packet detection on 5GHz */ --@@ -3194,14 +3200,8 @@ static void rt2800_config_channel(struct -- else -- rt2800_bbp_write(rt2x00dev, 105, 0x34); -- --- 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, 77, 0x98); -- } 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); -- } -- --@@ -6125,6 +6125,12 @@ static void rt2800_init_rfcsr_3290(struc -+@@ -6608,6 +6615,12 @@ static void rt2800_init_rfcsr_3290(struc - - static void rt2800_init_rfcsr_3352(struct rt2x00_dev *rt2x00dev) - { -@@ -46,7 +32,7 @@ - rt2800_rf_init_calibration(rt2x00dev, 30); - - rt2800_rfcsr_write(rt2x00dev, 0, 0xf0); --@@ -6160,15 +6166,30 @@ static void rt2800_init_rfcsr_3352(struc -+@@ -6643,15 +6656,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); -@@ -80,7 +66,7 @@ - rt2800_rfcsr_write(rt2x00dev, 43, 0xdb); - rt2800_rfcsr_write(rt2x00dev, 44, 0xdb); - rt2800_rfcsr_write(rt2x00dev, 45, 0xdb); --@@ -6176,15 +6197,20 @@ static void rt2800_init_rfcsr_3352(struc -+@@ -6659,15 +6687,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); -@@ -110,7 +96,7 @@ - rt2800_rfcsr_write(rt2x00dev, 59, 0x00); - rt2800_rfcsr_write(rt2x00dev, 60, 0x00); - rt2800_rfcsr_write(rt2x00dev, 61, 0x00); --@@ -7051,6 +7077,7 @@ static int rt2800_init_eeprom(struct rt2 -+@@ -7688,6 +7721,7 @@ static int rt2800_init_eeprom(struct rt2 - * RT53xx: defined in "EEPROM_CHIP_ID" field - */ - if (rt2x00_rt(rt2x00dev, RT3290) || -@@ -118,7 +104,7 @@ - rt2x00_rt(rt2x00dev, RT5390) || - rt2x00_rt(rt2x00dev, RT5392)) - rt2800_eeprom_read(rt2x00dev, EEPROM_CHIP_ID, &rf); --@@ -7142,7 +7169,8 @@ static int rt2800_init_eeprom(struct rt2 -+@@ -7782,7 +7816,8 @@ static int rt2800_init_eeprom(struct rt2 - /* - * Detect if this device has Bluetooth co-existence. - */ -@@ -128,7 +114,7 @@ - __set_bit(CAPABILITY_BT_COEXIST, &rt2x00dev->cap_flags); - - /* --@@ -7171,6 +7199,22 @@ static int rt2800_init_eeprom(struct rt2 -+@@ -7811,6 +7846,22 @@ static int rt2800_init_eeprom(struct rt2 - EIRP_MAX_TX_POWER_LIMIT) - __set_bit(CAPABILITY_POWER_LIMIT, &rt2x00dev->cap_flags); - -@@ -153,7 +139,7 @@ - - --- a/drivers/net/wireless/rt2x00/rt2800.h - +++ b/drivers/net/wireless/rt2x00/rt2800.h --@@ -2299,6 +2299,12 @@ struct mac_iveiv_entry { -+@@ -2333,6 +2333,12 @@ struct mac_iveiv_entry { - #define RFCSR36_RF_BS FIELD8(0x80) - - /* -@@ -166,7 +152,7 @@ - * RFCSR 38: - */ - #define RFCSR38_RX_LO1_EN FIELD8(0x20) --@@ -2310,6 +2316,18 @@ struct mac_iveiv_entry { -+@@ -2344,6 +2350,18 @@ struct mac_iveiv_entry { - #define RFCSR39_RX_LO2_EN FIELD8(0x80) - - /* -@@ -185,7 +171,7 @@ - * RFCSR 49: - */ - #define RFCSR49_TX FIELD8(0x3f) --@@ -2322,6 +2340,8 @@ struct mac_iveiv_entry { -+@@ -2356,6 +2374,8 @@ struct mac_iveiv_entry { - * RFCSR 50: - */ - #define RFCSR50_TX FIELD8(0x3f) -@@ -194,7 +180,7 @@ - #define RFCSR50_EP FIELD8(0xc0) - /* bits for RT3593 */ - #define RFCSR50_TX_LO1_EN FIELD8(0x20) --@@ -2469,6 +2489,8 @@ enum rt2800_eeprom_word { -+@@ -2503,6 +2523,8 @@ enum rt2800_eeprom_word { - * INTERNAL_TX_ALC: 0: disable, 1: enable - * BT_COEXIST: 0: disable, 1: enable - * DAC_TEST: 0: disable, 1: enable -@@ -203,7 +189,7 @@ - */ - #define EEPROM_NIC_CONF1_HW_RADIO FIELD16(0x0001) - #define EEPROM_NIC_CONF1_EXTERNAL_TX_ALC FIELD16(0x0002) --@@ -2485,6 +2507,8 @@ enum rt2800_eeprom_word { -+@@ -2519,6 +2541,8 @@ enum rt2800_eeprom_word { - #define EEPROM_NIC_CONF1_INTERNAL_TX_ALC FIELD16(0x2000) - #define EEPROM_NIC_CONF1_BT_COEXIST FIELD16(0x4000) - #define EEPROM_NIC_CONF1_DAC_TEST FIELD16(0x8000) -diff --git a/package/mac80211/patches/611-rt2x00-rf_vals-rt3352-xtal20.patch b/package/mac80211/patches/611-rt2x00-rf_vals-rt3352-xtal20.patch -index 478a0f2..65af89a 100644 ---- a/package/mac80211/patches/611-rt2x00-rf_vals-rt3352-xtal20.patch -+++ b/package/mac80211/patches/611-rt2x00-rf_vals-rt3352-xtal20.patch -@@ -1,6 +1,6 @@ - --- a/drivers/net/wireless/rt2x00/rt2800lib.c - +++ b/drivers/net/wireless/rt2x00/rt2800lib.c --@@ -7491,6 +7491,27 @@ static const struct rf_channel rf_vals_5 -+@@ -8198,6 +8198,27 @@ static const struct rf_channel rf_vals_5 - {196, 83, 0, 12, 1}, - }; - -@@ -28,7 +28,7 @@ - static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) - { - struct hw_mode_spec *spec = &rt2x00dev->spec; --@@ -7579,7 +7600,10 @@ static int rt2800_probe_hw_mode(struct r -+@@ -8285,7 +8306,10 @@ static int rt2800_probe_hw_mode(struct r - case RF5390: - case RF5392: - spec->num_channels = 14; -@@ -40,7 +40,7 @@ - break; - - case RF3052: --@@ -7755,6 +7779,19 @@ static int rt2800_probe_rt(struct rt2x00 -+@@ -8468,6 +8492,19 @@ static int rt2800_probe_rt(struct rt2x00 - return 0; - } - -@@ -59,8 +59,8 @@ - + - int rt2800_probe_hw(struct rt2x00_dev *rt2x00dev) - { -- int retval; --@@ -7784,6 +7821,15 @@ int rt2800_probe_hw(struct rt2x00_dev *r -+ struct rt2800_drv_data *drv_data = rt2x00dev->drv_data; -+@@ -8510,6 +8547,15 @@ int rt2800_probe_hw(struct rt2x00_dev *r - rt2800_register_write(rt2x00dev, GPIO_CTRL, reg); - - /* -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 -index f6b4808..119e95c 100644 ---- 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 -@@ -13,7 +13,7 @@ Signed-off-by: John Crispin - - --- a/drivers/net/wireless/rt2x00/rt2800soc.c - +++ b/drivers/net/wireless/rt2x00/rt2800soc.c --@@ -227,11 +227,18 @@ static int rt2800soc_probe(struct platfo -+@@ -237,11 +237,18 @@ static int rt2800soc_probe(struct platfo - return rt2x00soc_probe(pdev, &rt2800soc_ops); - } - -diff --git a/package/mac80211/patches/616-rt2x00-support-rt5350.patch b/package/mac80211/patches/616-rt2x00-support-rt5350.patch -index 3bafa16..41a7f34 100644 ---- a/package/mac80211/patches/616-rt2x00-support-rt5350.patch -+++ b/package/mac80211/patches/616-rt2x00-support-rt5350.patch -@@ -1,16 +1,16 @@ - --- a/drivers/net/wireless/rt2x00/rt2800.h - +++ b/drivers/net/wireless/rt2x00/rt2800.h --@@ -71,6 +71,7 @@ -- #define RF5592 0x000f -+@@ -73,6 +73,7 @@ - #define RF3070 0x3070 - #define RF3290 0x3290 -+ #define RF3853 0x3853 - +#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 --@@ -2704,6 +2704,13 @@ static void rt2800_config_channel_rf53xx -+@@ -3038,6 +3038,13 @@ static void rt2800_config_channel_rf53xx - - rt2800_rfcsr_write(rt2x00dev, 59, - r59_non_bt[idx]); -@@ -24,15 +24,15 @@ - } - } - } --@@ -3141,6 +3148,7 @@ static void rt2800_config_channel(struct -- rt2800_config_channel_rf3322(rt2x00dev, conf, rf, info); -+@@ -3516,6 +3523,7 @@ static void rt2800_config_channel(struct -+ rt2800_config_channel_rf3853(rt2x00dev, conf, rf, info); - break; - case RF3070: - + case RF5350: - case RF5360: - case RF5370: - case RF5372: --@@ -3158,6 +3166,7 @@ static void rt2800_config_channel(struct -+@@ -3533,6 +3541,7 @@ static void rt2800_config_channel(struct - if (rt2x00_rf(rt2x00dev, RF3070) || - rt2x00_rf(rt2x00dev, RF3290) || - rt2x00_rf(rt2x00dev, RF3322) || -@@ -40,7 +40,7 @@ - rt2x00_rf(rt2x00dev, RF5360) || - rt2x00_rf(rt2x00dev, RF5370) || - rt2x00_rf(rt2x00dev, RF5372) || --@@ -3398,7 +3407,8 @@ static void rt2800_config_channel(struct -+@@ -3810,7 +3819,8 @@ static void rt2800_config_channel(struct - /* - * Clear update flag - */ -@@ -50,15 +50,15 @@ - rt2800_bbp_read(rt2x00dev, 49, &bbp); - rt2x00_set_field8(&bbp, BBP49_UPDATE_FLAG, 0); - rt2800_bbp_write(rt2x00dev, 49, bbp); --@@ -4272,6 +4282,7 @@ void rt2800_vco_calibration(struct rt2x0 -- case RF3053: -+@@ -4689,6 +4699,7 @@ void rt2800_vco_calibration(struct rt2x0 - case RF3070: - case RF3290: -+ case RF3853: - + case RF5350: - case RF5360: - case RF5370: - case RF5372: --@@ -4668,6 +4679,8 @@ static int rt2800_init_registers(struct -+@@ -5101,6 +5112,8 @@ static int rt2800_init_registers(struct - rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000404); - rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606); - rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000); -@@ -67,7 +67,7 @@ - } else { - rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000000); - rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606); --@@ -5309,9 +5322,13 @@ static void rt2800_init_bbp_3352(struct -+@@ -5756,9 +5769,13 @@ static void rt2800_init_bbp_3352(struct - - rt2800_bbp_write(rt2x00dev, 82, 0x62); - -@@ -84,7 +84,7 @@ - - rt2800_bbp_write(rt2x00dev, 86, 0x38); - --@@ -5325,9 +5342,13 @@ static void rt2800_init_bbp_3352(struct -+@@ -5772,9 +5789,13 @@ static void rt2800_init_bbp_3352(struct - - rt2800_bbp_write(rt2x00dev, 104, 0x92); - -@@ -101,7 +101,7 @@ - - rt2800_bbp_write(rt2x00dev, 120, 0x50); - --@@ -5352,6 +5373,13 @@ static void rt2800_init_bbp_3352(struct -+@@ -5799,6 +5820,13 @@ static void rt2800_init_bbp_3352(struct - rt2800_bbp_write(rt2x00dev, 143, 0xa2); - - rt2800_bbp_write(rt2x00dev, 148, 0xc8); -@@ -115,7 +115,7 @@ - } - - static void rt2800_init_bbp_3390(struct rt2x00_dev *rt2x00dev) --@@ -5652,6 +5680,7 @@ static void rt2800_init_bbp(struct rt2x0 -+@@ -6140,6 +6168,7 @@ static void rt2800_init_bbp(struct rt2x0 - rt2800_init_bbp_3290(rt2x00dev); - break; - case RT3352: -@@ -123,8 +123,8 @@ - rt2800_init_bbp_3352(rt2x00dev); - break; - case RT3390: --@@ -6462,6 +6491,76 @@ static void rt2800_init_rfcsr_3593(struc -- /* TODO: enable stream mode support */ -+@@ -7091,6 +7120,76 @@ static void rt2800_init_rfcsr_3883(struc -+ rt2800_rfcsr_write(rt2x00dev, 20, rfcsr); - } - - +static void rt2800_init_rfcsr_5350(struct rt2x00_dev *rt2x00dev) -@@ -200,7 +200,7 @@ - static void rt2800_init_rfcsr_5390(struct rt2x00_dev *rt2x00dev) - { - rt2800_rf_init_calibration(rt2x00dev, 2); --@@ -6699,6 +6798,9 @@ static void rt2800_init_rfcsr(struct rt2 -+@@ -7331,6 +7430,9 @@ static void rt2800_init_rfcsr(struct rt2 - case RT3593: - rt2800_init_rfcsr_3593(rt2x00dev); - break; -@@ -210,7 +210,7 @@ - case RT5390: - rt2800_init_rfcsr_5390(rt2x00dev); - break; --@@ -6948,6 +7050,12 @@ static int rt2800_validate_eeprom(struct -+@@ -7590,6 +7692,12 @@ static int rt2800_validate_eeprom(struct - rt2x00_set_field16(&word, EEPROM_NIC_CONF0_RF_TYPE, RF2820); - rt2800_eeprom_write(rt2x00dev, EEPROM_NIC_CONF0, word); - rt2x00_eeprom_dbg(rt2x00dev, "Antenna: 0x%04x\n", word); -@@ -223,24 +223,24 @@ - } else if (rt2x00_rt(rt2x00dev, RT2860) || - rt2x00_rt(rt2x00dev, RT2872)) { - /* --@@ -7081,6 +7189,8 @@ static int rt2800_init_eeprom(struct rt2 -- rt2x00_rt(rt2x00dev, RT5390) || -- rt2x00_rt(rt2x00dev, RT5392)) -+@@ -7728,6 +7836,8 @@ static int rt2800_init_eeprom(struct rt2 - rt2800_eeprom_read(rt2x00dev, EEPROM_CHIP_ID, &rf); -+ else if (rt2x00_rt(rt2x00dev, RT3883)) -+ rf = RF3853; - + else if (rt2x00_rt(rt2x00dev, RT5350)) - + rf = RF5350; - else - rf = rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RF_TYPE); - --@@ -7099,6 +7209,7 @@ static int rt2800_init_eeprom(struct rt2 -- case RF3290: -+@@ -7747,6 +7857,7 @@ static int rt2800_init_eeprom(struct rt2 - case RF3320: - case RF3322: -+ case RF3853: - + case RF5350: - case RF5360: - case RF5370: - case RF5372: --@@ -7594,6 +7705,7 @@ static int rt2800_probe_hw_mode(struct r -+@@ -8301,6 +8412,7 @@ static int rt2800_probe_hw_mode(struct r - case RF3290: - case RF3320: - case RF3322: -@@ -248,18 +248,18 @@ - case RF5360: - case RF5370: - case RF5372: --@@ -7726,6 +7838,7 @@ static int rt2800_probe_hw_mode(struct r -- case RF3053: -+@@ -8439,6 +8551,7 @@ static int rt2800_probe_hw_mode(struct r - case RF3070: - case RF3290: -+ case RF3853: - + case RF5350: - case RF5360: - case RF5370: - case RF5372: --@@ -7764,6 +7877,7 @@ static int rt2800_probe_rt(struct rt2x00 -- case RT3390: -+@@ -8478,6 +8591,7 @@ static int rt2800_probe_rt(struct rt2x00 - case RT3572: - case RT3593: -+ case RT3883: - + case RT5350: - case RT5390: - case RT5392: -diff --git a/package/mac80211/patches/619-rt2x00-change-led-polarity-from-OF.patch b/package/mac80211/patches/619-rt2x00-change-led-polarity-from-OF.patch -index f9186d8..d966321 100644 ---- a/package/mac80211/patches/619-rt2x00-change-led-polarity-from-OF.patch -+++ b/package/mac80211/patches/619-rt2x00-change-led-polarity-from-OF.patch -@@ -1,6 +1,6 @@ - --- a/drivers/net/wireless/rt2x00/rt2800lib.c - +++ b/drivers/net/wireless/rt2x00/rt2800lib.c --@@ -36,6 +36,7 @@ -+@@ -37,6 +37,7 @@ - #include - #include - #include -@@ -8,7 +8,7 @@ - - #include "rt2x00.h" - #include "rt2800lib.h" --@@ -7298,6 +7299,17 @@ static int rt2800_init_eeprom(struct rt2 -+@@ -7946,6 +7947,17 @@ static int rt2800_init_eeprom(struct rt2 - rt2800_init_led(rt2x00dev, &rt2x00dev->led_assoc, LED_TYPE_ASSOC); - rt2800_init_led(rt2x00dev, &rt2x00dev->led_qual, LED_TYPE_QUALITY); - -diff --git a/package/mac80211/patches/620-rt2x00-add-AP+STA-support.patch b/package/mac80211/patches/620-rt2x00-add-AP+STA-support.patch -index 419cb60..ce667b8 100644 ---- a/package/mac80211/patches/620-rt2x00-add-AP+STA-support.patch -+++ b/package/mac80211/patches/620-rt2x00-add-AP+STA-support.patch -@@ -1,6 +1,6 @@ - --- a/drivers/net/wireless/rt2x00/rt2x00dev.c - +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c --@@ -1262,7 +1262,7 @@ static inline void rt2x00lib_set_if_comb -+@@ -1265,7 +1265,7 @@ static inline void rt2x00lib_set_if_comb - */ - if_limit = &rt2x00dev->if_limits_ap; - if_limit->max = rt2x00dev->ops->max_ap_intf; -diff --git a/package/mac80211/patches/620-rt2x00-rt3352-rf-id.patch b/package/mac80211/patches/620-rt2x00-rt3352-rf-id.patch -index 5e67344..90eab13 100644 ---- a/package/mac80211/patches/620-rt2x00-rt3352-rf-id.patch -+++ b/package/mac80211/patches/620-rt2x00-rt3352-rf-id.patch -@@ -1,6 +1,6 @@ - --- a/drivers/net/wireless/rt2x00/rt2800lib.c - +++ b/drivers/net/wireless/rt2x00/rt2800lib.c --@@ -7186,10 +7186,11 @@ static int rt2800_init_eeprom(struct rt2 -+@@ -7831,10 +7831,11 @@ static int rt2800_init_eeprom(struct rt2 - * RT53xx: defined in "EEPROM_CHIP_ID" field - */ - if (rt2x00_rt(rt2x00dev, RT3290) || -@@ -10,6 +10,6 @@ - rt2800_eeprom_read(rt2x00dev, EEPROM_CHIP_ID, &rf); - + else if (rt2x00_rt(rt2x00dev, RT3352)) - + rf = RF3322; -+ else if (rt2x00_rt(rt2x00dev, RT3883)) -+ rf = RF3853; - else if (rt2x00_rt(rt2x00dev, RT5350)) -- rf = RF5350; -- else -diff --git a/package/mac80211/patches/700-mwl8k-missing-pci-id-for-WNR854T.patch b/package/mac80211/patches/700-mwl8k-missing-pci-id-for-WNR854T.patch -index 484c075..ae7e927 100644 ---- a/package/mac80211/patches/700-mwl8k-missing-pci-id-for-WNR854T.patch -+++ b/package/mac80211/patches/700-mwl8k-missing-pci-id-for-WNR854T.patch -@@ -1,6 +1,6 @@ - --- a/drivers/net/wireless/mwl8k.c - +++ b/drivers/net/wireless/mwl8k.c --@@ -5529,6 +5529,7 @@ MODULE_FIRMWARE("mwl8k/fmimage_8366.fw") -+@@ -5682,6 +5682,7 @@ MODULE_FIRMWARE("mwl8k/fmimage_8366.fw") - MODULE_FIRMWARE(MWL8K_8366_AP_FW(MWL8K_8366_AP_FW_API)); - - static DEFINE_PCI_DEVICE_TABLE(mwl8k_pci_id_table) = { -diff --git a/package/mac80211/patches/800-b43-gpio-mask-module-option.patch b/package/mac80211/patches/800-b43-gpio-mask-module-option.patch -index fc874ad..7c56369 100644 ---- a/package/mac80211/patches/800-b43-gpio-mask-module-option.patch -+++ b/package/mac80211/patches/800-b43-gpio-mask-module-option.patch -@@ -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, --@@ -2747,10 +2752,10 @@ static int b43_gpio_init(struct b43_wlde -+@@ -2749,10 +2754,10 @@ static int b43_gpio_init(struct b43_wlde - u32 mask, set; - - b43_maskset32(dev, B43_MMIO_MACCTL, ~B43_MACCTL_GPOUTSMSK, 0); -diff --git a/package/mac80211/patches/810-b43_no_pio.patch b/package/mac80211/patches/810-b43_no_pio.patch -index 5cd1b8b..2023bf6 100644 ---- a/package/mac80211/patches/810-b43_no_pio.patch -+++ b/package/mac80211/patches/810-b43_no_pio.patch -@@ -11,7 +11,7 @@ - b43-$(CPTCFG_B43_PCMCIA) += pcmcia.o - --- a/drivers/net/wireless/b43/main.c - +++ b/drivers/net/wireless/b43/main.c --@@ -1915,10 +1915,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]); -@@ -75,12 +75,12 @@ - #endif /* B43_PIO_H_ */ - --- a/drivers/net/wireless/b43/Kconfig - +++ b/drivers/net/wireless/b43/Kconfig --@@ -98,7 +98,7 @@ config B43_BCMA_PIO -+@@ -118,7 +118,7 @@ config B43_BCMA_PIO - default y - - config B43_PIO - - bool - + bool "Broadcom 43xx PIO support" -- depends on B43 -+ depends on B43 && B43_SSB - select SSB_BLOCKIO - default y -diff --git a/package/mac80211/patches/820-b43-add-antenna-control.patch b/package/mac80211/patches/820-b43-add-antenna-control.patch -index dea9830..5a23967 100644 ---- a/package/mac80211/patches/820-b43-add-antenna-control.patch -+++ b/package/mac80211/patches/820-b43-add-antenna-control.patch -@@ -1,6 +1,6 @@ - --- a/drivers/net/wireless/b43/main.c - +++ b/drivers/net/wireless/b43/main.c --@@ -1562,7 +1562,7 @@ static void b43_write_beacon_template(st -+@@ -1556,7 +1556,7 @@ static void b43_write_beacon_template(st - len, ram_offset, shm_size_offset, rate); - - /* Write the PHY TX control parameters. */ -@@ -9,7 +9,7 @@ - antenna = b43_antenna_to_phyctl(antenna); - ctl = b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_BEACPHYCTL); - /* We can't send beacons with short preamble. Would get PHY errors. */ --@@ -3105,8 +3105,8 @@ static int b43_chip_init(struct b43_wlde -+@@ -3113,8 +3113,8 @@ static int b43_chip_init(struct b43_wlde - - /* Select the antennae */ - if (phy->ops->set_rx_antenna) -@@ -20,7 +20,7 @@ - - if (phy->type == B43_PHYTYPE_B) { - value16 = b43_read16(dev, 0x005E); --@@ -3850,7 +3850,6 @@ static int b43_op_config(struct ieee8021 -+@@ -3806,7 +3806,6 @@ static int b43_op_config(struct ieee8021 - struct b43_wldev *dev; - struct b43_phy *phy; - struct ieee80211_conf *conf = &hw->conf; -@@ -28,7 +28,7 @@ - int err = 0; - bool reload_bss = false; - --@@ -3904,11 +3903,9 @@ static int b43_op_config(struct ieee8021 -+@@ -3860,11 +3859,9 @@ static int b43_op_config(struct ieee8021 - } - - /* Antennas for RX and management frame TX. */ -@@ -42,7 +42,7 @@ - - if (wl->radio_enabled != phy->radio_on) { - if (wl->radio_enabled) { --@@ -5041,6 +5038,47 @@ static int b43_op_get_survey(struct ieee -+@@ -4988,6 +4985,47 @@ static int b43_op_get_survey(struct ieee - return 0; - } - -@@ -90,7 +90,7 @@ - static const struct ieee80211_ops b43_hw_ops = { - .tx = b43_op_tx, - .conf_tx = b43_op_conf_tx, --@@ -5062,6 +5100,8 @@ static const struct ieee80211_ops b43_hw -+@@ -5009,6 +5047,8 @@ static const struct ieee80211_ops b43_hw - .sw_scan_complete = b43_op_sw_scan_complete_notifier, - .get_survey = b43_op_get_survey, - .rfkill_poll = b43_rfkill_poll, -@@ -99,7 +99,7 @@ - }; - - /* Hard-reset the chip. Do not call this directly. --@@ -5308,6 +5348,8 @@ static int b43_one_core_attach(struct b4 -+@@ -5295,6 +5335,8 @@ static int b43_one_core_attach(struct b4 - if (!wldev) - goto out; - -@@ -108,7 +108,7 @@ - wldev->use_pio = b43_modparam_pio; - wldev->dev = dev; - wldev->wl = wl; --@@ -5398,6 +5440,9 @@ static struct b43_wl *b43_wireless_init( -+@@ -5385,6 +5427,9 @@ static struct b43_wl *b43_wireless_init( - - hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN; - -diff --git a/package/mac80211/patches/830-b43-workaround-pcie-bcm4716.patch b/package/mac80211/patches/830-b43-workaround-pcie-bcm4716.patch -index e76758c..b6db3ac 100644 ---- a/package/mac80211/patches/830-b43-workaround-pcie-bcm4716.patch -+++ b/package/mac80211/patches/830-b43-workaround-pcie-bcm4716.patch -@@ -19,7 +19,7 @@ Signed-off-by: Hauke Mehrtens - - --- a/drivers/net/wireless/b43/b43.h - +++ b/drivers/net/wireless/b43/b43.h --@@ -1061,6 +1061,31 @@ static inline bool b43_using_pio_transfe -+@@ -1054,6 +1054,31 @@ static inline bool b43_using_pio_transfe - return dev->__using_pio_transfers; - } - -@@ -53,18 +53,20 @@ Signed-off-by: Hauke Mehrtens - __printf(2, 3) void b43err(struct b43_wl *wl, const char *fmt, ...); - --- a/drivers/net/wireless/b43/bus.h - +++ b/drivers/net/wireless/b43/bus.h --@@ -60,6 +60,16 @@ static inline bool b43_bus_host_is_sdio( -- return (dev->bus_type == B43_BUS_SSB && -- dev->sdev->bus->bustype == SSB_BUSTYPE_SDIO); -+@@ -70,6 +70,18 @@ static inline bool b43_bus_host_is_sdio( -+ return false; -+ #endif - } - +static inline bool b43_bus_host_is_pci(struct b43_bus_dev *dev) - +{ --+ if (dev->bus_type == B43_BUS_SSB) --+ return (dev->sdev->bus->bustype == SSB_BUSTYPE_PCI); - +#ifdef CPTCFG_B43_BCMA - + if (dev->bus_type == B43_BUS_BCMA) - + return (dev->bdev->bus->hosttype == BCMA_HOSTTYPE_PCI); - +#endif -++#ifdef CPTCFG_B43_SSB -++ if (dev->bus_type == B43_BUS_SSB) -++ return (dev->sdev->bus->bustype == SSB_BUSTYPE_PCI); -++#endif - + return false; - +} - -@@ -72,7 +74,7 @@ Signed-off-by: Hauke Mehrtens - struct b43_bus_dev *b43_bus_dev_ssb_init(struct ssb_device *sdev); - --- a/drivers/net/wireless/b43/main.c - +++ b/drivers/net/wireless/b43/main.c --@@ -4437,7 +4437,7 @@ static int b43_phy_versioning(struct b43 -+@@ -4380,7 +4380,7 @@ static int b43_phy_versioning(struct b43 - u16 radio24[3]; - - for (tmp = 0; tmp < 3; tmp++) { -@@ -81,7 +83,7 @@ Signed-off-by: Hauke Mehrtens - radio24[tmp] = b43_read16(dev, B43_MMIO_RADIO24_DATA); - } - --@@ -4456,10 +4456,10 @@ static int b43_phy_versioning(struct b43 -+@@ -4399,10 +4399,10 @@ static int b43_phy_versioning(struct b43 - else - tmp = 0x5205017F; - } else { -@@ -96,7 +98,7 @@ Signed-off-by: Hauke Mehrtens - << 16; - --- a/drivers/net/wireless/b43/phy_common.c - +++ b/drivers/net/wireless/b43/phy_common.c --@@ -266,6 +266,12 @@ void b43_phy_write(struct b43_wldev *dev -+@@ -267,6 +267,12 @@ void b43_phy_write(struct b43_wldev *dev - { - assert_mac_suspended(dev); - dev->phy.ops->phy_write(dev, reg, value); -@@ -197,7 +199,7 @@ Signed-off-by: Hauke Mehrtens - - --- a/drivers/net/wireless/b43/phy_n.c - +++ b/drivers/net/wireless/b43/phy_n.c --@@ -5418,14 +5418,14 @@ static inline void check_phyreg(struct b -+@@ -5641,14 +5641,14 @@ static inline void check_phyreg(struct b - static u16 b43_nphy_op_read(struct b43_wldev *dev, u16 reg) - { - check_phyreg(dev, reg); -@@ -214,7 +216,7 @@ Signed-off-by: Hauke Mehrtens - b43_write16(dev, B43_MMIO_PHY_DATA, value); - } - --@@ -5433,7 +5433,7 @@ static void b43_nphy_op_maskset(struct b -+@@ -5656,7 +5656,7 @@ static void b43_nphy_op_maskset(struct b - u16 set) - { - check_phyreg(dev, reg); -@@ -223,16 +225,16 @@ Signed-off-by: Hauke Mehrtens - b43_maskset16(dev, B43_MMIO_PHY_DATA, mask, set); - } - --@@ -5444,7 +5444,7 @@ static u16 b43_nphy_op_radio_read(struct -- /* N-PHY needs 0x100 for read access */ -- reg |= 0x100; -+@@ -5670,7 +5670,7 @@ static u16 b43_nphy_op_radio_read(struct -+ else -+ reg |= 0x100; - - - b43_write16(dev, B43_MMIO_RADIO_CONTROL, reg); - + b43_wflush16(dev, B43_MMIO_RADIO_CONTROL, reg); - return b43_read16(dev, B43_MMIO_RADIO_DATA_LOW); - } - --@@ -5453,7 +5453,7 @@ static void b43_nphy_op_radio_write(stru -+@@ -5679,7 +5679,7 @@ static void b43_nphy_op_radio_write(stru - /* Register 1 is a 32-bit register. */ - B43_WARN_ON(reg == 1); - -diff --git a/package/mac80211/patches/845-b43-only-use-gpio-0-1-for-led.patch b/package/mac80211/patches/845-b43-only-use-gpio-0-1-for-led.patch -index 50347cd..efc3451 100644 ---- a/package/mac80211/patches/845-b43-only-use-gpio-0-1-for-led.patch -+++ b/package/mac80211/patches/845-b43-only-use-gpio-0-1-for-led.patch -@@ -1,6 +1,6 @@ - --- a/drivers/net/wireless/b43/main.c - +++ b/drivers/net/wireless/b43/main.c --@@ -2764,6 +2764,14 @@ static int b43_gpio_init(struct b43_wlde -+@@ -2766,6 +2766,14 @@ static int b43_gpio_init(struct b43_wlde - } else if (dev->dev->chip_id == 0x5354) { - /* Don't allow overtaking buttons GPIOs */ - set &= 0x2; /* 0x2 is LED GPIO on BCM5354 */ -diff --git a/package/mac80211/patches/900-wl1251-split-wl251-platform-data-to-a-separate-structure.patch b/package/mac80211/patches/900-wl1251-split-wl251-platform-data-to-a-separate-structure.patch -deleted file mode 100644 -index a8af257..0000000 ---- a/package/mac80211/patches/900-wl1251-split-wl251-platform-data-to-a-separate-structure.patch -+++ /dev/null -@@ -1,109 +0,0 @@ --Move the wl1251 part of the wl12xx platform data structure into a new --structure specifically for wl1251. Change the platform data built-in --block and board files accordingly. -- --Cc: Tony Lindgren --Signed-off-by: Luciano Coelho --Acked-by: Tony Lindgren --Reviewed-by: Felipe Balbi -- ----- a/drivers/net/wireless/ti/wilink_platform_data.c --+++ b/drivers/net/wireless/ti/wilink_platform_data.c --@@ -23,17 +23,17 @@ -- #include -- #include -- ---static struct wl12xx_platform_data *platform_data; --+static struct wl12xx_platform_data *wl12xx_platform_data; -- -- int __init wl12xx_set_platform_data(const struct wl12xx_platform_data *data) -- { --- if (platform_data) --+ if (wl12xx_platform_data) -- return -EBUSY; -- if (!data) -- return -EINVAL; -- --- platform_data = kmemdup(data, sizeof(*data), GFP_KERNEL); --- if (!platform_data) --+ wl12xx_platform_data = kmemdup(data, sizeof(*data), GFP_KERNEL); --+ if (!wl12xx_platform_data) -- return -ENOMEM; -- -- return 0; --@@ -41,9 +41,34 @@ int __init wl12xx_set_platform_data(cons -- -- struct wl12xx_platform_data *wl12xx_get_platform_data(void) -- { --- if (!platform_data) --+ if (!wl12xx_platform_data) -- return ERR_PTR(-ENODEV); -- --- return platform_data; --+ return wl12xx_platform_data; -- } -- EXPORT_SYMBOL(wl12xx_get_platform_data); --+ --+static struct wl1251_platform_data *wl1251_platform_data; --+ --+int __init wl1251_set_platform_data(const struct wl1251_platform_data *data) --+{ --+ if (wl1251_platform_data) --+ return -EBUSY; --+ if (!data) --+ return -EINVAL; --+ --+ wl1251_platform_data = kmemdup(data, sizeof(*data), GFP_KERNEL); --+ if (!wl1251_platform_data) --+ return -ENOMEM; --+ --+ return 0; --+} --+ --+struct wl1251_platform_data *wl1251_get_platform_data(void) --+{ --+ if (!wl1251_platform_data) --+ return ERR_PTR(-ENODEV); --+ --+ return wl1251_platform_data; --+} --+EXPORT_SYMBOL(wl1251_get_platform_data); ----- a/drivers/net/wireless/ti/wl1251/sdio.c --+++ b/drivers/net/wireless/ti/wl1251/sdio.c --@@ -227,7 +227,7 @@ static int wl1251_sdio_probe(struct sdio -- struct wl1251 *wl; -- struct ieee80211_hw *hw; -- struct wl1251_sdio *wl_sdio; --- const struct wl12xx_platform_data *wl12xx_board_data; --+ const struct wl1251_platform_data *wl1251_board_data; -- -- hw = wl1251_alloc_hw(); -- if (IS_ERR(hw)) --@@ -254,11 +254,11 @@ static int wl1251_sdio_probe(struct sdio -- wl->if_priv = wl_sdio; -- wl->if_ops = &wl1251_sdio_ops; -- --- wl12xx_board_data = wl12xx_get_platform_data(); --- if (!IS_ERR(wl12xx_board_data)) { --- wl->set_power = wl12xx_board_data->set_power; --- wl->irq = wl12xx_board_data->irq; --- wl->use_eeprom = wl12xx_board_data->use_eeprom; --+ wl1251_board_data = wl1251_get_platform_data(); --+ if (!IS_ERR(wl1251_board_data)) { --+ wl->set_power = wl1251_board_data->set_power; --+ wl->irq = wl1251_board_data->irq; --+ wl->use_eeprom = wl1251_board_data->use_eeprom; -- } -- -- if (wl->irq) { ----- a/drivers/net/wireless/ti/wl1251/spi.c --+++ b/drivers/net/wireless/ti/wl1251/spi.c --@@ -241,7 +241,7 @@ static const struct wl1251_if_operations -- -- static int wl1251_spi_probe(struct spi_device *spi) -- { --- struct wl12xx_platform_data *pdata; --+ struct wl1251_platform_data *pdata; -- struct ieee80211_hw *hw; -- struct wl1251 *wl; -- int ret; -diff --git a/package/mac80211/patches/900-wlcore-Add-support-for-DT-platform-data.patch b/package/mac80211/patches/900-wlcore-Add-support-for-DT-platform-data.patch -new file mode 100644 -index 0000000..856dea8 ---- /dev/null -+++ b/package/mac80211/patches/900-wlcore-Add-support-for-DT-platform-data.patch -@@ -0,0 +1,139 @@ -+When running with DT, we no longer have a board file that can set up the -+platform data for wlcore. Allow this data to be passed from DT. -+ -+Since some platforms use a gpio-irq, add support for passing either the -+irq number or the gpio number. For the latter case, the driver will -+request the gpio and convert it to the irq number. If an irq is -+specified, it'll be used as is. -+ -+[Arik - the pdev_data pointer does not belong to us and is freed when -+the device is released. Dereference to our private data first.] -+ -+Signed-off-by: Ido Yariv -+Signed-off-by: Arik Nemtsov -+--- -+ drivers/net/wireless/ti/wlcore/sdio.c | 71 ++++++++++++++++++++++++++++++++--- -+ include/linux/wl12xx.h | 3 +- -+ 2 files changed, 67 insertions(+), 7 deletions(-) -+ -+--- a/drivers/net/wireless/ti/wlcore/sdio.c -++++ b/drivers/net/wireless/ti/wlcore/sdio.c -+@@ -34,6 +34,7 @@ -+ #include -+ #include -+ #include -++#include -+ -+ #include "wlcore.h" -+ #include "wl12xx_80211.h" -+@@ -214,6 +215,61 @@ static struct wl1271_if_operations sdio_ -+ .set_block_size = wl1271_sdio_set_block_size, -+ }; -+ -++static const struct of_device_id wlcore_of_match[] = { -++ { -++ .compatible = "wlcore", -++ }, -++ {} -++}; -++MODULE_DEVICE_TABLE(of, wlcore_of_match); -++ -++static struct wl12xx_platform_data *get_platform_data(struct device *dev) -++{ -++ struct wl12xx_platform_data *pdata; -++ struct device_node *np; -++ u32 gpio; -++ -++ pdata = wl12xx_get_platform_data(); -++ if (!IS_ERR(pdata)) -++ return kmemdup(pdata, sizeof(*pdata), GFP_KERNEL); -++ -++ np = of_find_matching_node(NULL, wlcore_of_match); -++ if (!np) { -++ dev_err(dev, "No platform data set\n"); -++ return NULL; -++ } -++ -++ pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); -++ if (!pdata) { -++ dev_err(dev, "Can't allocate platform data\n"); -++ return NULL; -++ } -++ -++ if (of_property_read_u32(np, "irq", &pdata->irq)) { -++ if (!of_property_read_u32(np, "gpio", &gpio) && -++ !gpio_request_one(gpio, GPIOF_IN, "wlcore_irq")) { -++ pdata->gpio = gpio; -++ pdata->irq = gpio_to_irq(gpio); -++ } -++ } -++ -++ /* Optional fields */ -++ pdata->use_eeprom = of_property_read_bool(np, "use-eeprom"); -++ of_property_read_u32(np, "board-ref-clock", &pdata->board_ref_clock); -++ of_property_read_u32(np, "board-tcxo-clock", &pdata->board_tcxo_clock); -++ of_property_read_u32(np, "platform-quirks", &pdata->platform_quirks); -++ -++ return pdata; -++} -++ -++static void del_platform_data(struct wl12xx_platform_data *pdata) -++{ -++ if (pdata->gpio) -++ gpio_free(pdata->gpio); -++ -++ kfree(pdata); -++} -++ -+ static int wl1271_probe(struct sdio_func *func, -+ const struct sdio_device_id *id) -+ { -+@@ -245,10 +301,10 @@ static int wl1271_probe(struct sdio_func -+ /* Use block mode for transferring over one block size of data */ -+ func->card->quirks |= MMC_QUIRK_BLKSZ_FOR_BYTE_MODE; -+ -+- pdev_data.pdata = wl12xx_get_platform_data(); -+- if (IS_ERR(pdev_data.pdata)) { -+- ret = PTR_ERR(pdev_data.pdata); -+- dev_err(glue->dev, "missing wlan platform data: %d\n", ret); -++ pdev_data.pdata = get_platform_data(&func->dev); -++ if (!pdev_data.pdata) { -++ ret = -EINVAL; -++ dev_err(glue->dev, "missing wlan platform data\n"); -+ goto out_free_glue; -+ } -+ -+@@ -279,7 +335,7 @@ static int wl1271_probe(struct sdio_func -+ if (!glue->core) { -+ dev_err(glue->dev, "can't allocate platform_device"); -+ ret = -ENOMEM; -+- goto out_free_glue; -++ goto out_free_pdata; -+ } -+ -+ glue->core->dev.parent = &func->dev; -+@@ -313,6 +369,9 @@ static int wl1271_probe(struct sdio_func -+ out_dev_put: -+ platform_device_put(glue->core); -+ -++out_free_pdata: -++ del_platform_data(pdev_data->pdata); -++ -+ out_free_glue: -+ kfree(glue); -+ -+@@ -323,11 +382,14 @@ out: -+ static void wl1271_remove(struct sdio_func *func) -+ { -+ struct wl12xx_sdio_glue *glue = sdio_get_drvdata(func); -++ struct wlcore_platdev_data *pdev_data = glue->core->dev.platform_data; -++ struct wl12xx_platform_data *pdata = pdev_data->pdata; -+ -+ /* Undo decrement done above in wl1271_probe */ -+ pm_runtime_get_noresume(&func->dev); -+ -+ platform_device_unregister(glue->core); -++ del_platform_data(pdata); -+ kfree(glue); -+ } -+ -diff --git a/package/mac80211/patches/901-wlcore-don-t-switch-channels-on-disconnected-STA-vif.patch b/package/mac80211/patches/901-wlcore-don-t-switch-channels-on-disconnected-STA-vif.patch -new file mode 100644 -index 0000000..d90508e ---- /dev/null -+++ b/package/mac80211/patches/901-wlcore-don-t-switch-channels-on-disconnected-STA-vif.patch -@@ -0,0 +1,36 @@ -+From 4101e8dc540d19f1f6c24930629149191786e4cd Mon Sep 17 00:00:00 2001 -+From: Arik Nemtsov -+Date: Mon, 9 Sep 2013 16:48:59 +0300 -+Subject: [PATCH 27/75] wlcore: don't switch channels on disconnected STA vifs -+ -+Sending the FW a channel switch command on a disconnected vif may result -+in a beacon loss event. Avoid this edge case. -+ -+Signed-off-by: Arik Nemtsov -+--- -+ drivers/net/wireless/ti/wlcore/main.c | 7 +++++++ -+ 1 file changed, 7 insertions(+) -+ -+--- a/drivers/net/wireless/ti/wlcore/main.c -++++ b/drivers/net/wireless/ti/wlcore/main.c -+@@ -5148,6 +5148,10 @@ static void wl12xx_op_channel_switch(str -+ if (unlikely(wl->state == WLCORE_STATE_OFF)) { -+ wl12xx_for_each_wlvif_sta(wl, wlvif) { -+ struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif); -++ -++ if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags)) -++ continue; -++ -+ ieee80211_chswitch_done(vif, false); -+ } -+ goto out; -+@@ -5163,6 +5167,9 @@ static void wl12xx_op_channel_switch(str -+ wl12xx_for_each_wlvif_sta(wl, wlvif) { -+ unsigned long delay_usec; -+ -++ if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags)) -++ continue; -++ -+ ret = wl->ops->channel_switch(wl, wlvif, ch_switch); -+ if (ret) -+ goto out_sleep; -diff --git a/package/mac80211/patches/901-wlcore-set-irq_flags-in-the-board-files.patch b/package/mac80211/patches/901-wlcore-set-irq_flags-in-the-board-files.patch -deleted file mode 100644 -index f2789a9..0000000 ---- a/package/mac80211/patches/901-wlcore-set-irq_flags-in-the-board-files.patch -+++ /dev/null -@@ -1,118 +0,0 @@ --The platform_quirk element in the platform data was used to change the --way the IRQ is triggered. When set, the EDGE_IRQ quirk would change --the irqflags used and treat edge trigger differently from the rest. -- --Instead of hiding this irq flag setting behind the quirk, have the --board files set the flags during initialization. This will be more --meaningful than driver-specific quirks when we switch to DT. -- --Additionally, fix missing gpio_request() calls in the boarding files --(so that setting the flags actually works). -- --Cc: Tony Lindgren --Cc: Sekhar Nori --Signed-off-by: Luciano Coelho --Reviewed-by: Felipe Balbi --Acked-by: Sekhar Nori -- ----- a/drivers/net/wireless/ti/wlcore/debugfs.c --+++ b/drivers/net/wireless/ti/wlcore/debugfs.c --@@ -502,7 +502,7 @@ static ssize_t driver_state_read(struct -- DRIVER_STATE_PRINT_HEX(irq); -- /* TODO: ref_clock and tcxo_clock were moved to wl12xx priv */ -- DRIVER_STATE_PRINT_HEX(hw_pg_ver); --- DRIVER_STATE_PRINT_HEX(platform_quirks); --+ DRIVER_STATE_PRINT_HEX(irq_flags); -- DRIVER_STATE_PRINT_HEX(chip.id); -- DRIVER_STATE_PRINT_STR(chip.fw_ver_str); -- DRIVER_STATE_PRINT_STR(chip.phy_fw_ver_str); ----- a/drivers/net/wireless/ti/wlcore/main.c --+++ b/drivers/net/wireless/ti/wlcore/main.c --@@ -27,6 +27,7 @@ -- #include -- #include -- #include --+#include -- -- #include "wlcore.h" -- #include "debug.h" --@@ -528,7 +529,7 @@ static int wlcore_irq_locked(struct wl12 -- * In case edge triggered interrupt must be used, we cannot iterate -- * more than once without introducing race conditions with the hardirq. -- */ --- if (wl->platform_quirks & WL12XX_PLATFORM_QUIRK_EDGE_IRQ) --+ if (wl->irq_flags & IRQF_TRIGGER_RISING) -- loopcount = 1; -- -- wl1271_debug(DEBUG_IRQ, "IRQ work"); --@@ -5934,7 +5935,6 @@ struct ieee80211_hw *wlcore_alloc_hw(siz -- wl->ap_ps_map = 0; -- wl->ap_fw_ps_map = 0; -- wl->quirks = 0; --- wl->platform_quirks = 0; -- wl->system_hlid = WL12XX_SYSTEM_HLID; -- wl->active_sta_count = 0; -- wl->active_link_count = 0; --@@ -6075,7 +6075,7 @@ static void wlcore_nvs_cb(const struct f -- struct platform_device *pdev = wl->pdev; -- struct wlcore_platdev_data *pdev_data = dev_get_platdata(&pdev->dev); -- struct wl12xx_platform_data *pdata = pdev_data->pdata; --- unsigned long irqflags; --+ -- int ret; -- irq_handler_t hardirq_fn = NULL; -- --@@ -6103,29 +6103,19 @@ static void wlcore_nvs_cb(const struct f -- wlcore_adjust_conf(wl); -- -- wl->irq = platform_get_irq(pdev, 0); --- wl->platform_quirks = pdata->platform_quirks; -- wl->if_ops = pdev_data->if_ops; -- ---#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32) --- irqflags = IRQF_TRIGGER_RISING; --+ wl->irq_flags = irq_get_trigger_type(wl->irq) | IRQF_ONESHOT; -- hardirq_fn = wlcore_hardirq; ---#else --- if (wl->platform_quirks & WL12XX_PLATFORM_QUIRK_EDGE_IRQ) { --- irqflags = IRQF_TRIGGER_RISING; --- hardirq_fn = wlcore_hardirq; --- } else { --- irqflags = IRQF_TRIGGER_HIGH | IRQF_ONESHOT; --- } ---#endif -- -- #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,31) -- ret = compat_request_threaded_irq(&wl->irq_compat, wl->irq, -- hardirq_fn, wlcore_irq, --- irqflags, --+ wl->irqflags, -- pdev->name, wl); -- #else -- ret = request_threaded_irq(wl->irq, hardirq_fn, wlcore_irq, --- irqflags, pdev->name, wl); --+ wl->irq_flags, pdev->name, wl); -- #endif -- if (ret < 0) { -- wl1271_error("request_irq() failed: %d", ret); ----- a/drivers/net/wireless/ti/wlcore/wlcore.h --+++ b/drivers/net/wireless/ti/wlcore/wlcore.h --@@ -188,6 +188,8 @@ struct wl1271 { -- -- int irq; -- --+ int irq_flags; --+ -- spinlock_t wl_lock; -- -- enum wlcore_state state; --@@ -395,9 +397,6 @@ struct wl1271 { -- /* Quirks of specific hardware revisions */ -- unsigned int quirks; -- --- /* Platform limitations */ --- unsigned int platform_quirks; --- -- /* number of currently active RX BA sessions */ -- int ba_rx_session_count; -- -diff --git a/package/mac80211/patches/902-wlcore-remove-pwr_in_suspend-from-platform-data.patch b/package/mac80211/patches/902-wlcore-remove-pwr_in_suspend-from-platform-data.patch -deleted file mode 100644 -index 6394377..0000000 ---- a/package/mac80211/patches/902-wlcore-remove-pwr_in_suspend-from-platform-data.patch -+++ /dev/null -@@ -1,48 +0,0 @@ --The pwr_in_suspend flag depends on the MMC settings which can be --retrieved from the SDIO subsystem, so it doesn't need to be part of --the platform data structure. Move it to the platform device data that --is passed from SDIO to wlcore. -- --Signed-off-by: Luciano Coelho --Reviewed-by: Felipe Balbi -- ----- a/drivers/net/wireless/ti/wlcore/main.c --+++ b/drivers/net/wireless/ti/wlcore/main.c --@@ -6074,7 +6074,6 @@ static void wlcore_nvs_cb(const struct f -- struct wl1271 *wl = context; -- struct platform_device *pdev = wl->pdev; -- struct wlcore_platdev_data *pdev_data = dev_get_platdata(&pdev->dev); --- struct wl12xx_platform_data *pdata = pdev_data->pdata; -- -- int ret; -- irq_handler_t hardirq_fn = NULL; --@@ -6127,7 +6126,7 @@ static void wlcore_nvs_cb(const struct f -- if (!ret) { -- wl->irq_wake_enabled = true; -- device_init_wakeup(wl->dev, 1); --- if (pdata->pwr_in_suspend) --+ if (pdev_data->pwr_in_suspend) -- wl->hw->wiphy->wowlan = &wlcore_wowlan_support; -- } -- #endif ----- a/drivers/net/wireless/ti/wlcore/sdio.c --+++ b/drivers/net/wireless/ti/wlcore/sdio.c --@@ -260,7 +260,7 @@ static int wl1271_probe(struct sdio_func -- dev_dbg(glue->dev, "sdio PM caps = 0x%x\n", mmcflags); -- -- if (mmcflags & MMC_PM_KEEP_POWER) --- pdev_data->pdata->pwr_in_suspend = true; --+ pdev_data->pwr_in_suspend = true; -- -- sdio_set_drvdata(func, glue); -- ----- a/drivers/net/wireless/ti/wlcore/wlcore_i.h --+++ b/drivers/net/wireless/ti/wlcore/wlcore_i.h --@@ -209,6 +209,7 @@ struct wl1271_if_operations { -- struct wlcore_platdev_data { -- struct wl12xx_platform_data *pdata; -- struct wl1271_if_operations *if_ops; --+ bool pwr_in_suspend; -- }; -- -- #define MAX_NUM_KEYS 14 -diff --git a/package/mac80211/patches/903-wl12xx-use-frequency-instead-of-enumerations-for-pdata-clocks.patch b/package/mac80211/patches/903-wl12xx-use-frequency-instead-of-enumerations-for-pdata-clocks.patch -deleted file mode 100644 -index 4b20932..0000000 ---- a/package/mac80211/patches/903-wl12xx-use-frequency-instead-of-enumerations-for-pdata-clocks.patch -+++ /dev/null -@@ -1,131 +0,0 @@ --Instead of defining an enumeration with the FW specific values for the --different clock rates, use the actual frequency instead. Also add a --boolean to specify whether the clock is XTAL or not. -- --Change all board files to reflect this. -- --Additionally, this reverts commit 26f45c (ARM: OMAP2+: Legacy support --for wl12xx when booted with devicetree), since this is not be needed --anymore, now that DT support for WiLink is implemented. -- --Cc: Tony Lindgren --Cc: Sekhar Nori --Signed-off-by: Luciano Coelho --Reviewed-by: Felipe Balbi -- ----- a/drivers/net/wireless/ti/wl12xx/main.c --+++ b/drivers/net/wireless/ti/wl12xx/main.c --@@ -1711,6 +1711,43 @@ static struct ieee80211_sta_ht_cap wl12x -- }, -- }; -- --+static const struct wl12xx_clock wl12xx_refclock_table[] = { --+ { 19200000, false, WL12XX_REFCLOCK_19 }, --+ { 26000000, false, WL12XX_REFCLOCK_26 }, --+ { 26000000, true, WL12XX_REFCLOCK_26_XTAL }, --+ { 38400000, false, WL12XX_REFCLOCK_38 }, --+ { 38400000, true, WL12XX_REFCLOCK_38_XTAL }, --+ { 52000000, false, WL12XX_REFCLOCK_52 }, --+ { 0, false, 0 } --+}; --+ --+static const struct wl12xx_clock wl12xx_tcxoclock_table[] = { --+ { 16368000, true, WL12XX_TCXOCLOCK_16_368 }, --+ { 16800000, true, WL12XX_TCXOCLOCK_16_8 }, --+ { 19200000, true, WL12XX_TCXOCLOCK_19_2 }, --+ { 26000000, true, WL12XX_TCXOCLOCK_26 }, --+ { 32736000, true, WL12XX_TCXOCLOCK_32_736 }, --+ { 33600000, true, WL12XX_TCXOCLOCK_33_6 }, --+ { 38400000, true, WL12XX_TCXOCLOCK_38_4 }, --+ { 52000000, true, WL12XX_TCXOCLOCK_52 }, --+ { 0, false, 0 } --+}; --+ --+static int wl12xx_get_clock_idx(const struct wl12xx_clock *table, --+ u32 freq, bool xtal) --+{ --+ int i = 0; --+ --+ while(table[i].freq != 0) { --+ if ((table[i].freq == freq) && --+ (table[i].xtal == xtal)) --+ return table[i].hw_idx; --+ i++; --+ }; --+ --+ return -EINVAL; --+} --+ -- static int wl12xx_setup(struct wl1271 *wl) -- { -- struct wl12xx_priv *priv = wl->priv; --@@ -1732,7 +1769,16 @@ static int wl12xx_setup(struct wl1271 *w -- wl12xx_conf_init(wl); -- -- if (!fref_param) { --- priv->ref_clock = pdata->board_ref_clock; --+ priv->ref_clock = wl12xx_get_clock_idx(wl12xx_refclock_table, --+ pdata->ref_clock_freq, --+ pdata->ref_clock_xtal); --+ if (priv->ref_clock < 0) { --+ wl1271_error("Invalid ref_clock frequency (%d Hz, %s)", --+ pdata->ref_clock_freq, --+ pdata->ref_clock_xtal ? "XTAL" : "not XTAL"); --+ --+ return priv->ref_clock; --+ } -- } else { -- if (!strcmp(fref_param, "19.2")) -- priv->ref_clock = WL12XX_REFCLOCK_19; --@@ -1751,7 +1797,15 @@ static int wl12xx_setup(struct wl1271 *w -- } -- -- if (!tcxo_param) { --- priv->tcxo_clock = pdata->board_tcxo_clock; --+ priv->tcxo_clock = wl12xx_get_clock_idx(wl12xx_tcxoclock_table, --+ pdata->tcxo_clock_freq, --+ true); --+ if (priv->tcxo_clock < 0) { --+ wl1271_error("Invalid tcxo_clock frequency (%d Hz)", --+ pdata->tcxo_clock_freq); --+ --+ return priv->tcxo_clock; --+ } -- } else { -- if (!strcmp(tcxo_param, "19.2")) -- priv->tcxo_clock = WL12XX_TCXOCLOCK_19_2; ----- a/drivers/net/wireless/ti/wl12xx/wl12xx.h --+++ b/drivers/net/wireless/ti/wl12xx/wl12xx.h --@@ -79,4 +79,32 @@ struct wl12xx_priv { -- struct wl127x_rx_mem_pool_addr *rx_mem_addr; -- }; -- --+/* Reference clock values */ --+enum { --+ WL12XX_REFCLOCK_19 = 0, /* 19.2 MHz */ --+ WL12XX_REFCLOCK_26 = 1, /* 26 MHz */ --+ WL12XX_REFCLOCK_38 = 2, /* 38.4 MHz */ --+ WL12XX_REFCLOCK_52 = 3, /* 52 MHz */ --+ WL12XX_REFCLOCK_38_XTAL = 4, /* 38.4 MHz, XTAL */ --+ WL12XX_REFCLOCK_26_XTAL = 5, /* 26 MHz, XTAL */ --+}; --+ --+/* TCXO clock values */ --+enum { --+ WL12XX_TCXOCLOCK_19_2 = 0, /* 19.2MHz */ --+ WL12XX_TCXOCLOCK_26 = 1, /* 26 MHz */ --+ WL12XX_TCXOCLOCK_38_4 = 2, /* 38.4MHz */ --+ WL12XX_TCXOCLOCK_52 = 3, /* 52 MHz */ --+ WL12XX_TCXOCLOCK_16_368 = 4, /* 16.368 MHz */ --+ WL12XX_TCXOCLOCK_32_736 = 5, /* 32.736 MHz */ --+ WL12XX_TCXOCLOCK_16_8 = 6, /* 16.8 MHz */ --+ WL12XX_TCXOCLOCK_33_6 = 7, /* 33.6 MHz */ --+}; --+ --+struct wl12xx_clock { --+ u32 freq; --+ bool xtal; --+ u8 hw_idx; --+}; --+ -- #endif /* __WL12XX_PRIV_H__ */ -diff --git a/package/mac80211/patches/904-wlcore-add-initial-device-tree-support-to-the-sdio-module.patch b/package/mac80211/patches/904-wlcore-add-initial-device-tree-support-to-the-sdio-module.patch -deleted file mode 100644 -index 9e1d190..0000000 ---- a/package/mac80211/patches/904-wlcore-add-initial-device-tree-support-to-the-sdio-module.patch -+++ /dev/null -@@ -1,118 +0,0 @@ --If platform data is not available, try to get the required information --from the device tree. Register an OF match table and parse the --appropriate device tree nodes. -- --Parse interrupt property only, for now. -- --Signed-off-by: Luciano Coelho --Reviewed-by: Felipe Balbi -- ----- a/drivers/net/wireless/ti/wlcore/sdio.c --+++ b/drivers/net/wireless/ti/wlcore/sdio.c --@@ -30,7 +30,7 @@ -- #include -- #include -- #include ---#include --+#include -- #include -- #include -- #include --@@ -214,6 +214,43 @@ static struct wl1271_if_operations sdio_ -- .set_block_size = wl1271_sdio_set_block_size, -- }; -- --+static struct wl12xx_platform_data *wlcore_get_pdata_from_of(struct device *dev) --+{ --+ struct wl12xx_platform_data *pdata; --+ struct device_node *np = dev->of_node; --+ --+ if (!np) { --+ np = of_find_matching_node(NULL, dev->driver->of_match_table); --+ if (!np) { --+ dev_notice(dev, "device tree node not available\n"); --+ pdata = ERR_PTR(-ENODEV); --+ goto out; --+ } --+ } --+ --+ pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); --+ if (!pdata) { --+ dev_err(dev, "can't allocate platform data\n"); --+ pdata = ERR_PTR(-ENODEV); --+ goto out; --+ } --+ --+ pdata->irq = irq_of_parse_and_map(np, 0); --+ if (pdata->irq < 0) { --+ dev_err(dev, "can't get interrupt gpio from the device tree\n"); --+ goto out_free; --+ } --+ --+ goto out; --+ --+out_free: --+ kfree(pdata); --+ pdata = ERR_PTR(-ENODEV); --+ --+out: --+ return pdata; --+} --+ -- static int wl1271_probe(struct sdio_func *func, -- const struct sdio_device_id *id) -- { --@@ -248,11 +285,22 @@ static int wl1271_probe(struct sdio_func -- /* Use block mode for transferring over one block size of data */ -- func->card->quirks |= MMC_QUIRK_BLKSZ_FOR_BYTE_MODE; -- --+ /* The pdata allocated here is freed when the device is freed, --+ * so we don't need an additional out label to free it in case --+ * of error further on. --+ */ --+ --+ /* Try to get legacy platform data from the board file */ -- pdev_data->pdata = wl12xx_get_platform_data(); -- if (IS_ERR(pdev_data->pdata)) { --- ret = PTR_ERR(pdev_data->pdata); --- dev_err(glue->dev, "missing wlan platform data: %d\n", ret); --- goto out_free_glue; --+ dev_info(&func->dev, --+ "legacy platform data not found, trying device tree\n"); --+ --+ pdev_data->pdata = wlcore_get_pdata_from_of(&func->dev); --+ if (IS_ERR(pdev_data->pdata)) { --+ dev_err(&func->dev, "can't get platform data\n"); --+ goto out_free_glue; --+ } -- } -- -- /* if sdio can keep power while host is suspended, enable wow */ --@@ -386,16 +434,25 @@ static const struct dev_pm_ops wl1271_sd -- }; -- #endif -- --+static const struct of_device_id wlcore_sdio_of_match_table[] = { --+ { .compatible = "ti,wilink6" }, --+ { .compatible = "ti,wilink7" }, --+ { .compatible = "ti,wilink8" }, --+ { } --+}; --+MODULE_DEVICE_TABLE(of, wlcore_sdio_of_match_table); --+ -- static struct sdio_driver wl1271_sdio_driver = { -- .name = "wl1271_sdio", -- .id_table = wl1271_devices, -- .probe = wl1271_probe, -- .remove = wl1271_remove, ---#ifdef CONFIG_PM -- .drv = { --+#ifdef CONFIG_PM -- .pm = &wl1271_sdio_pm_ops, --- }, -- #endif --+ .of_match_table = of_match_ptr(wlcore_sdio_of_match_table), --+ }, -- }; -- -- static int __init wl1271_init(void) -diff --git a/package/mac80211/patches/905-wlcore-sdio-add-wilink-clock-providers.patch b/package/mac80211/patches/905-wlcore-sdio-add-wilink-clock-providers.patch -deleted file mode 100644 -index be1f9ad..0000000 ---- a/package/mac80211/patches/905-wlcore-sdio-add-wilink-clock-providers.patch -+++ /dev/null -@@ -1,50 +0,0 @@ --Add refclock and tcxoclock as clock providers in WiLink. These clocks --are not accesible outside the WiLink module, but they are registered --in the clock framework anyway. Only the WiLink chip consumes these --clocks. -- --In theory, the WiLink chip could be connected to external clocks --instead of using these internal clocks, so make the clock consumer --code generic enough. If external clocks are used, then the internal --clock device tree nodes are not necessary, but the external ones must --be specified. -- --Signed-off-by: Luciano Coelho --Reviewed-by: Felipe Balbi -- ----- a/drivers/net/wireless/ti/wlcore/sdio.c --+++ b/drivers/net/wireless/ti/wlcore/sdio.c --@@ -34,6 +34,7 @@ -- #include -- #include -- #include --+#include -- -- #include "wlcore.h" -- #include "wl12xx_80211.h" --@@ -214,10 +215,15 @@ static struct wl1271_if_operations sdio_ -- .set_block_size = wl1271_sdio_set_block_size, -- }; -- --+static const struct of_device_id wlcore_sdio_of_clk_match_table[] = { --+ { .compatible = "ti,wilink-clock" }, --+}; --+ -- static struct wl12xx_platform_data *wlcore_get_pdata_from_of(struct device *dev) -- { -- struct wl12xx_platform_data *pdata; -- struct device_node *np = dev->of_node; --+ struct device_node *clock_node; -- -- if (!np) { -- np = of_find_matching_node(NULL, dev->driver->of_match_table); --@@ -241,6 +247,9 @@ static struct wl12xx_platform_data *wlco -- goto out_free; -- } -- --+ for_each_matching_node(clock_node, wlcore_sdio_of_clk_match_table) --+ of_fixed_clk_setup(clock_node); --+ -- goto out; -- -- out_free: -diff --git a/package/mac80211/patches/906-wlcore-sdio-get-clocks-from-device-tree.patch b/package/mac80211/patches/906-wlcore-sdio-get-clocks-from-device-tree.patch -deleted file mode 100644 -index 09ff4af..0000000 ---- a/package/mac80211/patches/906-wlcore-sdio-get-clocks-from-device-tree.patch -+++ /dev/null -@@ -1,90 +0,0 @@ --Read the clock nodes from the device tree and use them to set the --frequency for the refclock and the tcxo clock. -- --Also, call sdio_set_drvdata() earlier, so the glue is already set in --the driver data when we call wlcore_get_pdata_from_of() and we don't --need to pass it as a parameter. -- --Signed-off-by: Luciano Coelho --Reviewed-by: Felipe Balbi -- ----- a/drivers/net/wireless/ti/wlcore/sdio.c --+++ b/drivers/net/wireless/ti/wlcore/sdio.c --@@ -53,6 +53,7 @@ static bool dump = false; -- struct wl12xx_sdio_glue { -- struct device *dev; -- struct platform_device *core; --+ struct clk *refclock, *tcxoclock; -- }; -- -- static const struct sdio_device_id wl1271_devices[] = { --@@ -224,6 +225,7 @@ static struct wl12xx_platform_data *wlco -- struct wl12xx_platform_data *pdata; -- struct device_node *np = dev->of_node; -- struct device_node *clock_node; --+ struct wl12xx_sdio_glue *glue = sdio_get_drvdata(dev_to_sdio_func(dev)); -- -- if (!np) { -- np = of_find_matching_node(NULL, dev->driver->of_match_table); --@@ -250,6 +252,26 @@ static struct wl12xx_platform_data *wlco -- for_each_matching_node(clock_node, wlcore_sdio_of_clk_match_table) -- of_fixed_clk_setup(clock_node); -- --+ /* TODO: make sure we have this when needed (ie. for WL6 and WL7) */ --+ glue->refclock = of_clk_get_by_name(np, "refclock"); --+ if (IS_ERR(glue->refclock)) { --+ dev_err(dev, "couldn't find refclock on the device tree\n"); --+ glue->refclock = NULL; --+ } else { --+ clk_prepare_enable(glue->refclock); --+ pdata->ref_clock_freq = clk_get_rate(glue->refclock); --+ } --+ --+ /* TODO: make sure we have this when needed (ie. for WL7) */ --+ glue->tcxoclock = of_clk_get_by_name(np, "tcxoclock"); --+ if (IS_ERR(glue->tcxoclock)) { --+ dev_err(dev, "couldn't find tcxoclock on the device tree\n"); --+ glue->tcxoclock = NULL; --+ } else { --+ clk_prepare_enable(glue->tcxoclock); --+ pdata->ref_clock_freq = clk_get_rate(glue->tcxoclock); --+ } --+ -- goto out; -- -- out_free: --@@ -294,6 +316,8 @@ static int wl1271_probe(struct sdio_func -- /* Use block mode for transferring over one block size of data */ -- func->card->quirks |= MMC_QUIRK_BLKSZ_FOR_BYTE_MODE; -- --+ sdio_set_drvdata(func, glue); --+ -- /* The pdata allocated here is freed when the device is freed, -- * so we don't need an additional out label to free it in case -- * of error further on. --@@ -319,8 +343,6 @@ static int wl1271_probe(struct sdio_func -- if (mmcflags & MMC_PM_KEEP_POWER) -- pdev_data->pwr_in_suspend = true; -- --- sdio_set_drvdata(func, glue); --- -- /* Tell PM core that we don't need the card to be powered now */ -- pm_runtime_put_noidle(&func->dev); -- --@@ -387,6 +409,16 @@ static void wl1271_remove(struct sdio_fu -- { -- struct wl12xx_sdio_glue *glue = sdio_get_drvdata(func); -- --+ if (glue->refclock) { --+ clk_disable_unprepare(glue->refclock); --+ clk_put(glue->refclock); --+ } --+ --+ if (glue->tcxoclock) { --+ clk_disable_unprepare(glue->tcxoclock); --+ clk_put(glue->tcxoclock); --+ } --+ -- /* Undo decrement done above in wl1271_probe */ -- pm_runtime_get_noresume(&func->dev); -- -diff --git a/package/mac80211/patches/907-wlcore-wl12xx-check-if-we-got-correct-clock-data-from-DT.patch b/package/mac80211/patches/907-wlcore-wl12xx-check-if-we-got-correct-clock-data-from-DT.patch -deleted file mode 100644 -index 6b09177..0000000 ---- a/package/mac80211/patches/907-wlcore-wl12xx-check-if-we-got-correct-clock-data-from-DT.patch -+++ /dev/null -@@ -1,96 +0,0 @@ --The fref and the tcxo clocks settings are optional in some platforms. --WiLink8 doesn't need either, so we don't check the values. WiLink 6 --only needs the fref clock, so we check that it is valid or return with --an error. WiLink7 needs both clocks, if either is not available we --return with an error. -- --Signed-off-by: Luciano Coelho --Reviewed-by: Felipe Balbi -- ----- a/drivers/net/wireless/ti/wl12xx/main.c --+++ b/drivers/net/wireless/ti/wl12xx/main.c --@@ -930,6 +930,11 @@ static int wl128x_boot_clk(struct wl1271 -- u16 sys_clk_cfg; -- int ret; -- --+ if ((priv->ref_clock < 0) || (priv->tcxo_clock < 0)) { --+ wl1271_error("Missing fref and/or tcxo clock settings\n"); --+ return -EINVAL; --+ } --+ -- /* For XTAL-only modes, FREF will be used after switching from TCXO */ -- if (priv->ref_clock == WL12XX_REFCLOCK_26_XTAL || -- priv->ref_clock == WL12XX_REFCLOCK_38_XTAL) { --@@ -979,6 +984,11 @@ static int wl127x_boot_clk(struct wl1271 -- u32 clk; -- int ret; -- --+ if (priv->ref_clock < 0) { --+ wl1271_error("Missing fref clock settings\n"); --+ return -EINVAL; --+ } --+ -- if (WL127X_PG_GET_MAJOR(wl->hw_pg_ver) < 3) -- wl->quirks |= WLCORE_QUIRK_END_OF_TRANSACTION; -- --@@ -1768,7 +1778,7 @@ static int wl12xx_setup(struct wl1271 *w -- wlcore_set_ht_cap(wl, IEEE80211_BAND_5GHZ, &wl12xx_ht_cap); -- wl12xx_conf_init(wl); -- --- if (!fref_param) { --+ if (!fref_param && (pdata->ref_clock_freq > 0)) { -- priv->ref_clock = wl12xx_get_clock_idx(wl12xx_refclock_table, -- pdata->ref_clock_freq, -- pdata->ref_clock_xtal); --@@ -1779,6 +1789,8 @@ static int wl12xx_setup(struct wl1271 *w -- -- return priv->ref_clock; -- } --+ } else if (!fref_param) { --+ priv->ref_clock = -EINVAL; -- } else { -- if (!strcmp(fref_param, "19.2")) -- priv->ref_clock = WL12XX_REFCLOCK_19; --@@ -1796,7 +1808,7 @@ static int wl12xx_setup(struct wl1271 *w -- wl1271_error("Invalid fref parameter %s", fref_param); -- } -- --- if (!tcxo_param) { --+ if (!fref_param && (pdata->tcxo_clock_freq > 0)) { -- priv->tcxo_clock = wl12xx_get_clock_idx(wl12xx_tcxoclock_table, -- pdata->tcxo_clock_freq, -- true); --@@ -1806,7 +1818,9 @@ static int wl12xx_setup(struct wl1271 *w -- -- return priv->tcxo_clock; -- } --- } else { --+ } else if (!fref_param) { --+ priv->tcxo_clock = -EINVAL; --+ }else { -- if (!strcmp(tcxo_param, "19.2")) -- priv->tcxo_clock = WL12XX_TCXOCLOCK_19_2; -- else if (!strcmp(tcxo_param, "26")) ----- a/drivers/net/wireless/ti/wlcore/sdio.c --+++ b/drivers/net/wireless/ti/wlcore/sdio.c --@@ -252,20 +252,16 @@ static struct wl12xx_platform_data *wlco -- for_each_matching_node(clock_node, wlcore_sdio_of_clk_match_table) -- of_fixed_clk_setup(clock_node); -- --- /* TODO: make sure we have this when needed (ie. for WL6 and WL7) */ -- glue->refclock = of_clk_get_by_name(np, "refclock"); -- if (IS_ERR(glue->refclock)) { --- dev_err(dev, "couldn't find refclock on the device tree\n"); -- glue->refclock = NULL; -- } else { -- clk_prepare_enable(glue->refclock); -- pdata->ref_clock_freq = clk_get_rate(glue->refclock); -- } -- --- /* TODO: make sure we have this when needed (ie. for WL7) */ -- glue->tcxoclock = of_clk_get_by_name(np, "tcxoclock"); -- if (IS_ERR(glue->tcxoclock)) { --- dev_err(dev, "couldn't find tcxoclock on the device tree\n"); -- glue->tcxoclock = NULL; -- } else { -- clk_prepare_enable(glue->tcxoclock); -diff --git a/package/mac80211/patches/a01-compat_fix_compile.patch b/package/mac80211/patches/a01-compat_fix_compile.patch -new file mode 100644 -index 0000000..9e9e6c7 ---- /dev/null -+++ b/package/mac80211/patches/a01-compat_fix_compile.patch -@@ -0,0 +1,15 @@ -+--- a/compat/compat-3.6.c -++++ b/compat/compat-3.6.c -+@@ -148,6 +148,7 @@ int sg_alloc_table_from_pages(struct sg_ -+ } -+ EXPORT_SYMBOL_GPL(sg_alloc_table_from_pages); -+ -++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)) -+ /* whoopsie ! */ -+ #ifndef CONFIG_COMMON_CLK -+ int clk_enable(struct clk *clk) -+@@ -161,3 +162,4 @@ void clk_disable(struct clk *clk) -+ } -+ EXPORT_SYMBOL_GPL(clk_disable); -+ #endif -++#endif -diff --git a/target/linux/generic/files/include/linux/ath9k_platform.h b/target/linux/generic/files/include/linux/ath9k_platform.h -index a0b7531..03aa636 100644 ---- a/target/linux/generic/files/include/linux/ath9k_platform.h -+++ b/target/linux/generic/files/include/linux/ath9k_platform.h -@@ -39,6 +39,8 @@ struct ath9k_platform_data { - int (*get_mac_revision)(void); - int (*external_reset)(void); - -+ bool use_eeprom; -+ - int num_leds; - const struct gpio_led *leds; - }; diff --git a/patches/openwrt/0019-ar71xx-add-support-for-QCA953x-SoC.patch b/patches/openwrt/0018-ar71xx-add-support-for-QCA953x-SoC.patch similarity index 100% rename from patches/openwrt/0019-ar71xx-add-support-for-QCA953x-SoC.patch rename to patches/openwrt/0018-ar71xx-add-support-for-QCA953x-SoC.patch diff --git a/patches/openwrt/0020-ar71xx-add-support-for-the-TP-LINK-TL-WR841N-ND-v9.patch b/patches/openwrt/0019-ar71xx-add-support-for-the-TP-LINK-TL-WR841N-ND-v9.patch similarity index 100% rename from patches/openwrt/0020-ar71xx-add-support-for-the-TP-LINK-TL-WR841N-ND-v9.patch rename to patches/openwrt/0019-ar71xx-add-support-for-the-TP-LINK-TL-WR841N-ND-v9.patch diff --git a/patches/openwrt/0021-Backport-support-for-TL-WR842N-v2-and-TL-MR3420-v2.patch b/patches/openwrt/0020-Backport-support-for-TL-WR842N-v2-and-TL-MR3420-v2.patch similarity index 100% rename from patches/openwrt/0021-Backport-support-for-TL-WR842N-v2-and-TL-MR3420-v2.patch rename to patches/openwrt/0020-Backport-support-for-TL-WR842N-v2-and-TL-MR3420-v2.patch diff --git a/patches/openwrt/0022-x86-add-grub2-iso-support.patch b/patches/openwrt/0021-x86-add-grub2-iso-support.patch similarity index 100% rename from patches/openwrt/0022-x86-add-grub2-iso-support.patch rename to patches/openwrt/0021-x86-add-grub2-iso-support.patch diff --git a/patches/openwrt/0023-x86-explicitely-pass-staging-directory-to-grub-mkimage-instead-of-relying-on-build-time-defaults-12821.patch b/patches/openwrt/0022-x86-explicitely-pass-staging-directory-to-grub-mkimage-instead-of-relying-on-build-time-defaults-12821.patch similarity index 100% rename from patches/openwrt/0023-x86-explicitely-pass-staging-directory-to-grub-mkimage-instead-of-relying-on-build-time-defaults-12821.patch rename to patches/openwrt/0022-x86-explicitely-pass-staging-directory-to-grub-mkimage-instead-of-relying-on-build-time-defaults-12821.patch diff --git a/patches/openwrt/0024-grub2-Add-sub-package-grub-editenv-for-target-installation.patch b/patches/openwrt/0023-grub2-Add-sub-package-grub-editenv-for-target-installation.patch similarity index 100% rename from patches/openwrt/0024-grub2-Add-sub-package-grub-editenv-for-target-installation.patch rename to patches/openwrt/0023-grub2-Add-sub-package-grub-editenv-for-target-installation.patch diff --git a/patches/openwrt/0025-x86-Fix-CONFIG_X86_GRUB_SERIAL.patch b/patches/openwrt/0024-x86-Fix-CONFIG_X86_GRUB_SERIAL.patch similarity index 100% rename from patches/openwrt/0025-x86-Fix-CONFIG_X86_GRUB_SERIAL.patch rename to patches/openwrt/0024-x86-Fix-CONFIG_X86_GRUB_SERIAL.patch diff --git a/patches/openwrt/0026-grub2-update-to-2.02-beta2-fixes-mac-os-x-10.9-support-and-many-other-things.patch b/patches/openwrt/0025-grub2-update-to-2.02-beta2-fixes-mac-os-x-10.9-support-and-many-other-things.patch similarity index 100% rename from patches/openwrt/0026-grub2-update-to-2.02-beta2-fixes-mac-os-x-10.9-support-and-many-other-things.patch rename to patches/openwrt/0025-grub2-update-to-2.02-beta2-fixes-mac-os-x-10.9-support-and-many-other-things.patch diff --git a/patches/openwrt/0027-grub2-disable-libdevmapper-fix-build-when-it-s-available.patch b/patches/openwrt/0026-grub2-disable-libdevmapper-fix-build-when-it-s-available.patch similarity index 100% rename from patches/openwrt/0027-grub2-disable-libdevmapper-fix-build-when-it-s-available.patch rename to patches/openwrt/0026-grub2-disable-libdevmapper-fix-build-when-it-s-available.patch diff --git a/patches/openwrt/0028-grub2-disable-mkfont-fix-build-on-Archlinux.patch b/patches/openwrt/0027-grub2-disable-mkfont-fix-build-on-Archlinux.patch similarity index 100% rename from patches/openwrt/0028-grub2-disable-mkfont-fix-build-on-Archlinux.patch rename to patches/openwrt/0027-grub2-disable-mkfont-fix-build-on-Archlinux.patch diff --git a/patches/openwrt/0029-ar71xx-add-support-for-dlink-dir-615-e1.patch b/patches/openwrt/0028-ar71xx-add-support-for-dlink-dir-615-e1.patch similarity index 100% rename from patches/openwrt/0029-ar71xx-add-support-for-dlink-dir-615-e1.patch rename to patches/openwrt/0028-ar71xx-add-support-for-dlink-dir-615-e1.patch