From: Felix Fietkau Date: Thu, 22 Dec 2011 06:05:25 +0000 (+0000) Subject: mac80211: backport from trunk X-Git-Url: http://git.openwrt.org/?a=commitdiff_plain;h=672de4d311b51f2abec2b11c73fb21af972516ce;p=openwrt%2Fsvn-archive%2Farchive.git mac80211: backport from trunk SVN-Revision: 29599 --- diff --git a/package/mac80211/Makefile b/package/mac80211/Makefile index 92ea37009b..1a06cef3d4 100644 --- a/package/mac80211/Makefile +++ b/package/mac80211/Makefile @@ -10,10 +10,10 @@ include $(INCLUDE_DIR)/kernel.mk PKG_NAME:=mac80211 -PKG_VERSION:=2011-11-15 +PKG_VERSION:=2011-12-01 PKG_RELEASE:=1 PKG_SOURCE_URL:=http://mirror2.openwrt.org/sources -PKG_MD5SUM:=0bb667c7fecbc244840d806df0604661 +PKG_MD5SUM:=8d1fe2fd6bbabc4fbbf31dfbf015c62c PKG_SOURCE:=compat-wireless-$(PKG_VERSION).tar.bz2 PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/compat-wireless-$(PKG_VERSION) @@ -32,6 +32,7 @@ PKG_CONFIG_DEPENDS:= \ CONFIG_PACKAGE_kmod-mac80211 \ $(patsubst %,CONFIG_PACKAGE_kmod-%,$(PKG_DRIVERS)) \ CONFIG_PACKAGE_MAC80211_DEBUGFS \ + CONFIG_PACKAGE_MAC80211_MESH \ CONFIG_PACKAGE_ATH_DEBUG \ CONFIG_PACKAGE_B43_DEBUG \ CONFIG_PACKAGE_B43_PIO \ @@ -89,6 +90,10 @@ define KernelPackage/mac80211/config Say N unless you know you need this. + config PACKAGE_MAC80211_MESH + bool "Enable 802.11s mesh support" + default y + endmenu endef @@ -704,7 +709,7 @@ define KernelPackage/iwl-legacy $(call KernelPackage/mac80211/Default) DEPENDS:= +kmod-mac80211 @PCI_SUPPORT TITLE:=Intel legacy Wireless support - FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/iwlegacy/iwl-legacy.ko + FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/iwlegacy/iwlegacy.ko AUTOLOAD:=$(call AutoLoad,60,iwl-legacy) endef @@ -766,6 +771,14 @@ ifneq ($(CONFIG_B43_FW_4_178),) PKG_B43_FWV4_SOURCE:=$(PKG_B43_FWV4_NAME)-$(PKG_B43_FWV4_VERSION).tar.bz2 PKG_B43_FWV4_SOURCE_URL:=http://mirror2.openwrt.org/sources/ PKG_B43_FWV4_MD5SUM:=14477e8cbbb91b11896affac9b219fdb +else +ifneq ($(CONFIG_B43_FW_5_100_138),) + PKG_B43_FWV4_NAME:=broadcom-wl + PKG_B43_FWV4_VERSION:=5.100.138 + PKG_B43_FWV4_OBJECT:=$(PKG_B43_FWV4_NAME)-$(PKG_B43_FWV4_VERSION)/linux/wl_apsta.o + PKG_B43_FWV4_SOURCE:=$(PKG_B43_FWV4_NAME)-$(PKG_B43_FWV4_VERSION).tar.bz2 + PKG_B43_FWV4_SOURCE_URL:=http://www.lwfinger.com/b43-firmware/ + PKG_B43_FWV4_MD5SUM:=f4e357b09eaf5d8b1f1920cf3493a555 else PKG_B43_FWV4_NAME:=broadcom-wl PKG_B43_FWV4_VERSION:=4.150.10.5 @@ -775,6 +788,7 @@ else PKG_B43_FWV4_MD5SUM:=0c6ba9687114c6b598e8019e262d9a60 endif endif +endif ifneq ($(CONFIG_B43_OPENFIRMWARE),) PKG_B43_FWV4_NAME:=broadcom-wl PKG_B43_FWV4_VERSION:=5.2 @@ -801,11 +815,11 @@ ifeq ($(CONFIG_B43_OPENFIRMWARE),y) PKG_B43_FWCUTTER_OBJECT:=$(PKG_B43_FWCUTTER_NAME)-$(PKG_B43_FWCUTTER_VERSION)/fwcutter/ else PKG_B43_FWCUTTER_NAME:=b43-fwcutter - PKG_B43_FWCUTTER_VERSION:=014 + PKG_B43_FWCUTTER_VERSION:=015 PKG_B43_FWCUTTER_SOURCE:=$(PKG_B43_FWCUTTER_NAME)-$(PKG_B43_FWCUTTER_VERSION).tar.bz2 PKG_B43_FWCUTTER_PROTO:=default PKG_B43_FWCUTTER_SOURCE_URL:=http://bu3sch.de/b43/fwcutter/ - PKG_B43_FWCUTTER_MD5SUM:=dd63f9149510bd6e01b89314e955083b + PKG_B43_FWCUTTER_MD5SUM:=628e030565222a107bc40300313cbe76 PKG_B43_FWCUTTER_SUBDIR:=b43-fwcutter-$(PKG_B43_FWCUTTER_VERSION) PKG_B43_FWCUTTER_OBJECT:=$(PKG_B43_FWCUTTER_NAME)-$(PKG_B43_FWCUTTER_VERSION)/ endif @@ -886,6 +900,15 @@ define KernelPackage/b43/config If unsure, select the "stable" firmware. + config B43_FW_5_100_138 + bool "Firmware 666.2 from driver 5.100.138" + help + Newer experimental firmware for BCM43xx devices. + + This firmware is mostly untested. It is needed for some N-PHY devices. + + If unsure, select the "stable" firmware. + config B43_OPENFIRMWARE bool "Open FirmWare for WiFi networks" help @@ -964,14 +987,33 @@ define KernelPackage/b43/config config PACKAGE_B43_PHY_N bool "Enable support for N-PHYs" - select B43_FW_5_10 - depends BROKEN - default n + depends on BROKEN + select B43_FW_5_100_138 help Enable support for BCM4321 and BCM4322. Currently only 11g speed is available. + If unsure, say Y. + + config PACKAGE_B43_PHY_HT + bool "Enable support for HT-PHYs" + depends on BROKEN + select B43_FW_5_100_138 + default n + help + Currently broken. + + If unsure, say N. + + config PACKAGE_B43_PHY_LCN + bool "Enable support for LCN-PHYs" + depends on BROKEN + select B43_FW_5_100_138 + default n + help + Currently broken. + If unsure, say N. endmenu @@ -1032,13 +1074,18 @@ BUILDFLAGS:= \ $(if $(CONFIG_PCI),-DCONFIG_ATH9K_PCI) \ $(if $(CONFIG_TARGET_ar71xx),-DCONFIG_ATH9K_AHB) \ $(if $(CONFIG_PACKAGE_MAC80211_DEBUGFS), -DCONFIG_CFG80211_DEBUGFS -DCONFIG_MAC80211_DEBUGFS -DCONFIG_ATH9K_DEBUGFS -DCONFIG_CARL9170_DEBUGFS -DCONFIG_ATH9K_HTC_DEBUGFS -DCONFIG_ATH5K_DEBUG) \ + $(if $(CONFIG_PACKAGE_MAC80211_MESH),-DCONFIG_MAC80211_MESH) \ $(if $(CONFIG_PACKAGE_ATH_DEBUG),-DCONFIG_ATH_DEBUG -DCONFIG_ATH9K_PKTLOG) \ -D__CONFIG_MAC80211_RC_DEFAULT=minstrel \ -DCONFIG_MAC80211_RC_MINSTREL_HT \ $(if $(CONFIG_ATH_USER_REGD),-DATH_USER_REGD=1) \ $(if $(CONFIG_PACKAGE_B43_DEBUG),-DCONFIG_B43_DEBUG) \ $(if $(CONFIG_PACKAGE_B43_PIO),-DCONFIG_B43_PIO) \ + $(if $(CONFIG_PACKAGE_B43_PIO),-DCONFIG_B43_BCMA_PIO) \ $(if $(CONFIG_PACKAGE_B43_PHY_N),-DCONFIG_B43_PHY_N) \ + $(if $(CONFIG_PACKAGE_B43_PHY_HT),-DCONFIG_B43_PHY_HT) \ + $(if $(CONFIG_PACKAGE_B43_PHY_LCN),-DCONFIG_B43_PHY_LCN) \ + -DCONFIG_B43_BCMA \ -DCONFIG_B43_SSB \ $(if $(CONFIG_PACKAGE_RT2X00_LIB_DEBUGFS),-DCONFIG_RT2X00_LIB_DEBUGFS) \ $(if $(CONFIG_PACKAGE_RT2X00_DEBUG),-DCONFIG_RT2X00_DEBUG) \ @@ -1062,6 +1109,7 @@ MAKE_OPTS:= \ CONFIG_CFG80211=$(if $(CONFIG_PACKAGE_kmod-cfg80211),m) \ CONFIG_MAC80211=$(if $(CONFIG_PACKAGE_kmod-mac80211),m) \ CONFIG_MAC80211_RC_MINSTREL=y \ + CONFIG_MAC80211_MESH=$(CONFIG_PACKAGE_MAC80211_MESH) \ CONFIG_MAC80211_LEDS=$(CONFIG_LEDS_TRIGGERS) \ CONFIG_CFG80211_DEBUGFS=$(if $(CONFIG_PACKAGE_MAC80211_DEBUGFS),y) \ CONFIG_MAC80211_DEBUGFS=$(if $(CONFIG_PACKAGE_MAC80211_DEBUGFS),y) \ @@ -1076,7 +1124,11 @@ MAKE_OPTS:= \ CONFIG_B43LEGACY=$(if $(CONFIG_PACKAGE_kmod-b43legacy),m) \ CONFIG_B43_DEBUG=$(if $(CONFIG_PACKAGE_B43_DEBUG),y) \ CONFIG_B43_PIO=$(if $(CONFIG_PACKAGE_B43_PIO),y) \ + CONFIG_B43_BCMA_PIO=$(if $(CONFIG_PACKAGE_B43_PIO),y) \ CONFIG_B43_PHY_N=$(if $(CONFIG_PACKAGE_B43_PHY_N),y) \ + CONFIG_B43_PHY_HT=$(if $(CONFIG_PACKAGE_B43_PHY_HT),y) \ + CONFIG_B43_PHY_LCN=$(if $(CONFIG_PACKAGE_B43_PHY_LCN),y) \ + CONFIG_B43_BCMA=y \ CONFIG_B43_SSB=y \ CONFIG_ATH_COMMON=$(if $(CONFIG_PACKAGE_kmod-ath),m) \ CONFIG_ATH_DEBUG=$(if $(CONFIG_PACKAGE_ATH_DEBUG),y) \ @@ -1142,7 +1194,7 @@ MAKE_OPTS:= \ CONFIG_LIB80211_CRYPT_CCMP=$(if $(CONFIG_PACKAGE_kmod-lib80211),m) \ CONFIG_LIB80211_CRYPT_TKIP=$(if $(CONFIG_PACKAGE_kmod-lib80211),m) \ CONFIG_IWLWIFI=$(if $(CONFIG_PACKAGE_kmod-iwlagn),m) \ - CONFIG_IWLWIFI_LEGACY=$(if $(CONFIG_PACKAGE_kmod-iwl-legacy),m) \ + CONFIG_IWLEGACY=$(if $(CONFIG_PACKAGE_kmod-iwl-legacy),m) \ CONFIG_COMPAT_IWL4965=$(if $(CONFIG_PACKAGE_kmod-iwl4965),m) \ CONFIG_IWL3945=$(if $(CONFIG_PACKAGE_kmod-iwl3945),m) \ CONFIG_MWL8K=$(if $(CONFIG_PACKAGE_kmod-mwl8k),m) \ diff --git a/package/mac80211/diff.txt b/package/mac80211/diff.txt new file mode 100644 index 0000000000..50afc0cb63 --- /dev/null +++ b/package/mac80211/diff.txt @@ -0,0 +1,89 @@ +--- Makefile 2011-12-22 06:58:51.000000000 +0100 ++++ /Users/nbd/openwrt/package/mac80211/Makefile 2011-12-17 16:40:06.000000000 +0100 +@@ -49,7 +49,7 @@ + SUBMENU:=$(WMENU) + URL:=http://linuxwireless.org/ + MAINTAINER:=Felix Fietkau +- DEPENDS:=@(!(TARGET_avr32||TARGET_ep93xx)||BROKEN) @!LINUX_2_4 ++ DEPENDS:=@(!(TARGET_avr32||TARGET_ep93xx||TARGET_ps3||TARGET_pxcab||LINUX_3_2)||BROKEN) + endef + + define KernelPackage/cfg80211 +@@ -164,7 +164,7 @@ + + define KernelPackage/p54-common + $(call KernelPackage/p54/Default) +- DEPENDS+= @PCI_SUPPORT||@USB_SUPPORT||@TARGET_omap24xx +kmod-mac80211 +kmod-crc-ccitt ++ DEPENDS+= @PCI_SUPPORT||@USB_SUPPORT||@TARGET_omap24xx +kmod-mac80211 +kmod-lib-crc-ccitt + TITLE+= (COMMON) + FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/p54/p54common.ko + AUTOLOAD:=$(call AutoLoad,30,p54common) +@@ -207,7 +207,7 @@ + + define KernelPackage/rt2x00-lib + $(call KernelPackage/rt2x00/Default) +- DEPENDS+= @(PCI_SUPPORT||USB_SUPPORT||TARGET_ramips) +kmod-mac80211 +kmod-crc-itu-t ++ DEPENDS+= @(PCI_SUPPORT||USB_SUPPORT||TARGET_ramips) +kmod-mac80211 +kmod-lib-crc-itu-t + TITLE+= (LIB) + FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/rt2x00/rt2x00lib.ko + AUTOLOAD:=$(call AutoLoad,25,rt2x00lib) +@@ -308,7 +308,7 @@ + + define KernelPackage/rt2800-pci + $(call KernelPackage/rt2x00/Default) +- DEPENDS+= @(PCI_SUPPORT||TARGET_ramips) +kmod-rt2x00-pci +kmod-rt2800-lib +kmod-crc-ccitt +TARGET_ramips:kmod-rt2x00-soc ++ DEPENDS+= @(PCI_SUPPORT||TARGET_ramips) +kmod-rt2x00-pci +kmod-rt2800-lib +kmod-lib-crc-ccitt +TARGET_ramips:kmod-rt2x00-soc + TITLE+= (RT2860 PCI) + FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/rt2x00/rt2800pci.ko + AUTOLOAD:=$(call AutoLoad,28,rt2800pci) +@@ -316,7 +316,7 @@ + + define KernelPackage/rt2800-usb + $(call KernelPackage/rt2x00/Default) +- DEPENDS+= @USB_SUPPORT +kmod-rt2x00-usb +kmod-rt2800-lib +kmod-crc-ccitt ++ DEPENDS+= @USB_SUPPORT +kmod-rt2x00-usb +kmod-rt2800-lib +kmod-lib-crc-ccitt + TITLE+= (RT2870 USB) + FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/rt2x00/rt2800usb.ko + AUTOLOAD:=$(call AutoLoad,28,rt2800usb) +@@ -859,6 +859,7 @@ + + define KernelPackage/b43 + $(call KernelPackage/b43-common) ++ DEPENDS+= +@DRIVER_11N_SUPPORT +!TARGET_brcm47xx:kmod-bcma + TITLE:=Broadcom 43xx wireless support + FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/b43/b43.ko + AUTOLOAD:=$(call AutoLoad,30,b43) +@@ -938,7 +939,7 @@ + config B43_FW_SQUASH_COREREVS + string "Core revisions to include" + depends on B43_FW_SQUASH +- default "5,6,7,8,9,10,13,14,15" ++ default "5,6,7,8,9,10,11,13,14,15,16" + help + This is a comma seperated list of core revision numbers. + +@@ -951,7 +952,7 @@ + config B43_FW_SQUASH_PHYTYPES + string "PHY types to include" + depends on B43_FW_SQUASH +- default "G,LP" ++ default "G,LP,N" + help + This is a comma seperated list of PHY types: + A => A-PHY +@@ -977,7 +978,6 @@ + + config PACKAGE_B43_PIO + bool "Enable support for PIO transfer mode" +- depends BROKEN + default n + help + Enable support for using PIO instead of DMA. Unless you have DMA +@@ -1250,6 +1250,7 @@ + $(TAR) -C $(PKG_BUILD_DIR) -xjf $(DL_DIR)/$(ZD1211FW_NAME)-$(ZD1211FW_VERSION).tar.bz2 + $(TAR) -C $(PKG_BUILD_DIR) -xjf $(DL_DIR)/$(PKG_LINUX_FIRMWARE_SOURCE) + rm -rf $(PKG_BUILD_DIR)/include/linux/ssb ++ rm -rf $(PKG_BUILD_DIR)/include/linux/bcma + rm -f $(PKG_BUILD_DIR)/include/net/ieee80211.h + endef + diff --git a/package/mac80211/files/host_bin/b43-fwsquash.py b/package/mac80211/files/host_bin/b43-fwsquash.py index 1e3696483b..3a2ea13cd6 100755 --- a/package/mac80211/files/host_bin/b43-fwsquash.py +++ b/package/mac80211/files/host_bin/b43-fwsquash.py @@ -70,6 +70,8 @@ revmapping = { "ucode14.fw" : (14,), "ucode15.fw" : (15,), "ucode16_mimo.fw" : (16,), + "ucode24_mimo.fw" : (24,), + "ucode29_mimo.fw" : (29,), "pcm4.fw" : (1,2,3,4,), "pcm5.fw" : (5,6,7,8,9,10,), } @@ -93,6 +95,8 @@ initvalmapping = { "lp0bsinitvals13.fw" : ( (13,), ("LP",), ), "lp0bsinitvals14.fw" : ( (14,), ("LP",), ), "lp0bsinitvals15.fw" : ( (15,), ("LP",), ), + "lcn0initvals24.fw" : ( (24,), ("LNC",), ), + "ht0initvals29.fw" : ( (29,), ("HT",), ), } for f in fwfiles: diff --git a/package/mac80211/files/lib/wifi/mac80211.sh b/package/mac80211/files/lib/wifi/mac80211.sh index 738c2aa412..974fe5f994 100644 --- a/package/mac80211/files/lib/wifi/mac80211.sh +++ b/package/mac80211/files/lib/wifi/mac80211.sh @@ -363,7 +363,7 @@ enable_mac80211() { iw phy "$phy" interface add "$ifname" type managed $wdsflag config_get_bool powersave "$vif" powersave 0 [ "$powersave" -gt 0 ] && powersave="on" || powersave="off" - iwconfig "$ifname" power "$powersave" + iw "$ifname" set power_save "$powersave" ;; esac @@ -394,12 +394,6 @@ enable_mac80211() { [ -n "$fixed" -a -n "$channel" ] && iw dev "$ifname" set channel "$channel" fi - config_get vif_txpower "$vif" txpower - # use vif_txpower (from wifi-iface) to override txpower (from - # wifi-device) if the latter doesn't exist - txpower="${txpower:-$vif_txpower}" - [ -z "$txpower" ] || iw dev "$ifname" set txpower fixed "${txpower%%.*}00" - i=$(($i + 1)) done @@ -434,6 +428,12 @@ enable_mac80211() { [ ! "$mode" = "ap" ] || continue ifconfig "$ifname" up + config_get vif_txpower "$vif" txpower + # use vif_txpower (from wifi-iface) to override txpower (from + # wifi-device) if the latter doesn't exist + txpower="${txpower:-$vif_txpower}" + [ -z "$txpower" ] || iw dev "$ifname" set txpower fixed "${txpower%%.*}00" + if [ ! "$mode" = "ap" ]; then ifconfig "$ifname" up case "$mode" in diff --git a/package/mac80211/patches/001-disable_b44.patch b/package/mac80211/patches/001-disable_b44.patch index 547a453eac..52564d1d8d 100644 --- a/package/mac80211/patches/001-disable_b44.patch +++ b/package/mac80211/patches/001-disable_b44.patch @@ -1,6 +1,6 @@ --- a/config.mk +++ b/config.mk -@@ -339,8 +339,8 @@ CONFIG_B43_BCMA_PIO=y +@@ -378,8 +378,8 @@ CONFIG_B43_BCMA_PIO=y CONFIG_P54_PCI=m diff --git a/package/mac80211/patches/002-disable_rfkill.patch b/package/mac80211/patches/002-disable_rfkill.patch index 4ba30479fa..82f31ae638 100644 --- a/package/mac80211/patches/002-disable_rfkill.patch +++ b/package/mac80211/patches/002-disable_rfkill.patch @@ -1,6 +1,6 @@ --- a/config.mk +++ b/config.mk -@@ -87,7 +87,7 @@ endif # build check +@@ -95,7 +95,7 @@ endif # build check endif # kernel Makefile check # These both are needed by compat-wireless || compat-bluetooth so enable them @@ -9,7 +9,7 @@ ifeq ($(CONFIG_MAC80211),y) $(error "ERROR: you have MAC80211 compiled into the kernel, CONFIG_MAC80211=y, as such you cannot replace its mac80211 driver. You need this set to CONFIG_MAC80211=m. If you are using Fedora upgrade your kernel as later version should this set as modular. For further information on Fedora see https://bugzilla.redhat.com/show_bug.cgi?id=470143. If you are using your own kernel recompile it and make mac80211 modular") -@@ -632,10 +632,10 @@ endif #CONFIG_COMPAT_KERNEL_2_6_27 +@@ -671,10 +671,10 @@ endif #CONFIG_COMPAT_KERNEL_2_6_27 # We need the backported rfkill module on kernel < 2.6.31. # In more recent kernel versions use the in kernel rfkill module. ifdef CONFIG_COMPAT_KERNEL_2_6_31 diff --git a/package/mac80211/patches/003-disable_bt.patch b/package/mac80211/patches/003-disable_bt.patch index ebccddde6e..d93b0cd2c0 100644 --- a/package/mac80211/patches/003-disable_bt.patch +++ b/package/mac80211/patches/003-disable_bt.patch @@ -1,6 +1,6 @@ --- a/config.mk +++ b/config.mk -@@ -109,8 +109,8 @@ ifndef CONFIG_COMPAT_KERNEL_2_6_27 +@@ -117,8 +117,8 @@ ifndef CONFIG_COMPAT_KERNEL_2_6_27 ifeq ($(CONFIG_BT),y) # we'll ignore compiling bluetooth else diff --git a/package/mac80211/patches/005-disable_ssb_build.patch b/package/mac80211/patches/005-disable_ssb_build.patch index ac95769059..8e898145e6 100644 --- a/package/mac80211/patches/005-disable_ssb_build.patch +++ b/package/mac80211/patches/005-disable_ssb_build.patch @@ -18,7 +18,7 @@ else include $(KLIB_BUILD)/.config endif -@@ -315,7 +314,8 @@ CONFIG_IPW2200_QOS=y +@@ -354,7 +353,8 @@ CONFIG_IPW2200_QOS=y # % echo 1 > /sys/bus/pci/drivers/ipw2200/*/rtap_iface endif #CONFIG_WIRELESS_EXT @@ -28,7 +28,7 @@ # Sonics Silicon Backplane CONFIG_SSB_SPROM=y -@@ -328,7 +328,7 @@ endif #CONFIG_PCMCIA +@@ -367,7 +367,7 @@ endif #CONFIG_PCMCIA # CONFIG_SSB_DEBUG=y CONFIG_SSB_DRIVER_PCICORE=y CONFIG_B43_SSB=y @@ -37,7 +37,7 @@ CONFIG_BCMA=m CONFIG_BCMA_BLOCKIO=y -@@ -535,7 +535,6 @@ endif #CONFIG_SPI_MASTER end of SPI driv +@@ -574,7 +574,6 @@ endif #CONFIG_SPI_MASTER end of SPI driv ifdef CONFIG_MMC diff --git a/package/mac80211/patches/006-disable_bcma_build.patch b/package/mac80211/patches/006-disable_bcma_build.patch index 8a82d7ed96..2d8cdd8f2b 100644 --- a/package/mac80211/patches/006-disable_bcma_build.patch +++ b/package/mac80211/patches/006-disable_bcma_build.patch @@ -10,7 +10,7 @@ ifeq ($(CONFIG_STAGING_EXCLUDE_BUILD),) --- a/config.mk +++ b/config.mk -@@ -330,12 +330,12 @@ CONFIG_SSB_DRIVER_PCICORE=y +@@ -369,12 +369,12 @@ CONFIG_SSB_DRIVER_PCICORE=y CONFIG_B43_SSB=y endif #__CONFIG_SSB diff --git a/package/mac80211/patches/007-remove_misc_drivers.patch b/package/mac80211/patches/007-remove_misc_drivers.patch index 0b4b26ef57..1181c42af5 100644 --- a/package/mac80211/patches/007-remove_misc_drivers.patch +++ b/package/mac80211/patches/007-remove_misc_drivers.patch @@ -1,6 +1,6 @@ --- a/config.mk +++ b/config.mk -@@ -213,7 +213,7 @@ $(warning "WARNING: CONFIG_CFG80211_WEXT +@@ -252,7 +252,7 @@ $(warning "WARNING: CONFIG_CFG80211_WEXT endif #CONFIG_WIRELESS_EXT ifdef CONFIG_STAGING @@ -9,7 +9,7 @@ endif #CONFIG_STAGING # mac80211 test driver -@@ -367,13 +367,13 @@ endif #CONFIG_CRC_ITU_T +@@ -406,13 +406,13 @@ endif #CONFIG_CRC_ITU_T CONFIG_MWL8K=m # Ethernet drivers go here @@ -28,7 +28,7 @@ endif #CONFIG_COMPAT_KERNEL_2_6_27 ifdef CONFIG_WIRELESS_EXT -@@ -432,21 +432,21 @@ endif #CONFIG_COMPAT_KERNEL_2_6_29 +@@ -471,21 +471,21 @@ endif #CONFIG_COMPAT_KERNEL_2_6_29 # Note: this depends on CONFIG_USB_NET_RNDIS_HOST and CONFIG_USB_NET_CDCETHER # it also requires new RNDIS_HOST and CDC_ETHER modules which we add ifdef CONFIG_COMPAT_KERNEL_2_6_29 diff --git a/package/mac80211/patches/008-disable_mesh.patch b/package/mac80211/patches/008-disable_mesh.patch new file mode 100644 index 0000000000..3c00938afc --- /dev/null +++ b/package/mac80211/patches/008-disable_mesh.patch @@ -0,0 +1,11 @@ +--- a/config.mk ++++ b/config.mk +@@ -188,7 +188,7 @@ CONFIG_MAC80211_LEDS=y + endif #CONFIG_LEDS_TRIGGERS + + # enable mesh networking too +-CONFIG_MAC80211_MESH=y ++# CONFIG_MAC80211_MESH=y + + CONFIG_CFG80211=m + CONFIG_CFG80211_DEFAULT_PS=y diff --git a/package/mac80211/patches/009-remove_mac80211_module_dependence.patch b/package/mac80211/patches/009-remove_mac80211_module_dependence.patch index ed67de27c9..2e3753e13c 100644 --- a/package/mac80211/patches/009-remove_mac80211_module_dependence.patch +++ b/package/mac80211/patches/009-remove_mac80211_module_dependence.patch @@ -1,6 +1,6 @@ --- a/config.mk +++ b/config.mk -@@ -50,23 +50,6 @@ $(error "ERROR: Your 2.6.27 kernel has C +@@ -58,23 +58,6 @@ $(error "ERROR: Your 2.6.27 kernel has C endif endif diff --git a/package/mac80211/patches/010-no_pcmcia.patch b/package/mac80211/patches/010-no_pcmcia.patch index f6b89d86bc..4cb88a96f9 100644 --- a/package/mac80211/patches/010-no_pcmcia.patch +++ b/package/mac80211/patches/010-no_pcmcia.patch @@ -9,7 +9,7 @@ else include $(KLIB_BUILD)/.config endif -@@ -247,7 +247,7 @@ CONFIG_B43=m +@@ -286,7 +286,7 @@ CONFIG_B43=m CONFIG_B43_HWRNG=y CONFIG_B43_PCI_AUTOSELECT=y ifdef CONFIG_PCMCIA diff --git a/package/mac80211/patches/011-no_sdio.patch b/package/mac80211/patches/011-no_sdio.patch index fc2e6d9b60..919f1ac5ac 100644 --- a/package/mac80211/patches/011-no_sdio.patch +++ b/package/mac80211/patches/011-no_sdio.patch @@ -1,6 +1,6 @@ --- a/config.mk +++ b/config.mk -@@ -518,7 +518,7 @@ endif #CONFIG_SPI_MASTER end of SPI driv +@@ -557,7 +557,7 @@ endif #CONFIG_SPI_MASTER end of SPI driv ifdef CONFIG_MMC diff --git a/package/mac80211/patches/013-disable_b43_nphy.patch b/package/mac80211/patches/013-disable_b43_nphy.patch index f9f13e21bd..287285fc03 100644 --- a/package/mac80211/patches/013-disable_b43_nphy.patch +++ b/package/mac80211/patches/013-disable_b43_nphy.patch @@ -1,6 +1,6 @@ --- a/config.mk +++ b/config.mk -@@ -253,8 +253,8 @@ ifdef CONFIG_MAC80211_LEDS +@@ -292,8 +292,8 @@ ifdef CONFIG_MAC80211_LEDS CONFIG_B43_LEDS=y endif #CONFIG_MAC80211_LEDS CONFIG_B43_PHY_LP=y diff --git a/package/mac80211/patches/015-remove-rt2x00-options.patch b/package/mac80211/patches/015-remove-rt2x00-options.patch index 18490c584a..fdf34c3a14 100644 --- a/package/mac80211/patches/015-remove-rt2x00-options.patch +++ b/package/mac80211/patches/015-remove-rt2x00-options.patch @@ -1,6 +1,6 @@ --- a/config.mk +++ b/config.mk -@@ -329,7 +329,7 @@ CONFIG_RTL8180=m +@@ -368,7 +368,7 @@ CONFIG_RTL8180=m CONFIG_ADM8211=m @@ -9,7 +9,7 @@ CONFIG_RT2400PCI=m CONFIG_RT2500PCI=m ifdef CONFIG_CRC_CCITT -@@ -467,7 +467,7 @@ CONFIG_RT2800USB_RT35XX=y +@@ -506,7 +506,7 @@ CONFIG_RT2800USB_RT35XX=y # CONFIG_RT2800USB_RT53XX=y CONFIG_RT2800USB_UNKNOWN=y endif #CONFIG_CRC_CCITT diff --git a/package/mac80211/patches/016-remove_pid_algo.patch b/package/mac80211/patches/016-remove_pid_algo.patch index b003f4c525..9d22e75385 100644 --- a/package/mac80211/patches/016-remove_pid_algo.patch +++ b/package/mac80211/patches/016-remove_pid_algo.patch @@ -1,6 +1,6 @@ --- a/config.mk +++ b/config.mk -@@ -124,7 +124,7 @@ CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y +@@ -163,7 +163,7 @@ CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y # This is the one used by our compat-wireless net/mac80211/rate.c # in case you have and old kernel which is overriding this to pid. CONFIG_COMPAT_MAC80211_RC_DEFAULT=minstrel_ht diff --git a/package/mac80211/patches/017-remove_ath9k_rc.patch b/package/mac80211/patches/017-remove_ath9k_rc.patch index f3415564dd..ad1f1466d2 100644 --- a/package/mac80211/patches/017-remove_ath9k_rc.patch +++ b/package/mac80211/patches/017-remove_ath9k_rc.patch @@ -1,6 +1,6 @@ --- a/config.mk +++ b/config.mk -@@ -220,7 +220,7 @@ CONFIG_ATH9K_COMMON=m +@@ -259,7 +259,7 @@ CONFIG_ATH9K_COMMON=m # as default once we get minstrel properly tested and blessed by # our systems engineering team. CCK rates also need to be used # for long range considerations. diff --git a/package/mac80211/patches/019-remove_ath5k_pci_option.patch b/package/mac80211/patches/019-remove_ath5k_pci_option.patch index 9de0418562..513d435d38 100644 --- a/package/mac80211/patches/019-remove_ath5k_pci_option.patch +++ b/package/mac80211/patches/019-remove_ath5k_pci_option.patch @@ -1,6 +1,6 @@ --- a/config.mk +++ b/config.mk -@@ -225,7 +225,7 @@ CONFIG_ATH9K_COMMON=m +@@ -264,7 +264,7 @@ CONFIG_ATH9K_COMMON=m # PCI Drivers ifdef CONFIG_PCI @@ -8,4 +8,4 @@ +# CONFIG_ATH5K_PCI=y CONFIG_ATH9K_PCI=y - CONFIG_IWLAGN=m + CONFIG_IWLWIFI=m diff --git a/package/mac80211/patches/021-add_include_for_bcma.patch b/package/mac80211/patches/021-add_include_for_bcma.patch index 6d1bc64461..21b624e791 100644 --- a/package/mac80211/patches/021-add_include_for_bcma.patch +++ b/package/mac80211/patches/021-add_include_for_bcma.patch @@ -1,8 +1,8 @@ --- a/include/linux/compat-3.0.h +++ b/include/linux/compat-3.0.h -@@ -5,6 +5,8 @@ +@@ -7,6 +7,8 @@ - #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0)) + #include +#include + diff --git a/package/mac80211/patches/022-atomic64_backport.patch b/package/mac80211/patches/022-atomic64_backport.patch deleted file mode 100644 index 673b7c336a..0000000000 --- a/package/mac80211/patches/022-atomic64_backport.patch +++ /dev/null @@ -1,91 +0,0 @@ ---- a/compat/Makefile -+++ b/compat/Makefile -@@ -38,3 +38,8 @@ compat-$(CONFIG_COMPAT_KERNEL_3_1) += \ - cordic.o \ - crc8.o - -+ifndef CONFIG_64BIT -+ifndef CONFIG_GENERIC_ATOMIC64 -+ compat-y += compat_atomic.o -+endif -+endif ---- a/include/linux/compat-2.6.31.h -+++ b/include/linux/compat-2.6.31.h -@@ -202,6 +202,20 @@ void compat_synchronize_threaded_irq(str - #define skb_walk_frags(skb, iter) \ - for (iter = skb_shinfo(skb)->frag_list; iter; iter = iter->next) - -+#ifndef CONFIG_64BIT -+ -+typedef struct { -+ long long counter; -+} atomic64_t; -+ -+extern long long atomic64_read(const atomic64_t *v); -+extern long long atomic64_add_return(long long a, atomic64_t *v); -+ -+#define atomic64_inc_return(v) atomic64_add_return(1LL, (v)) -+ -+#endif -+ -+ - #endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,31)) */ - - #endif /* LINUX_26_31_COMPAT_H */ ---- /dev/null -+++ b/compat/compat_atomic.c -@@ -0,0 +1,33 @@ -+#include -+#include -+ -+#if !((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,31)) && (defined(CONFIG_UML) || defined(CONFIG_X86))) && !((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,33)) && defined(CONFIG_ARM) && !defined(CONFIG_GENERIC_ATOMIC64)) -+ -+static DEFINE_SPINLOCK(lock); -+ -+long long atomic64_read(const atomic64_t *v) -+{ -+ unsigned long flags; -+ long long val; -+ -+ spin_lock_irqsave(&lock, flags); -+ val = v->counter; -+ spin_unlock_irqrestore(&lock, flags); -+ return val; -+} -+EXPORT_SYMBOL(atomic64_read); -+ -+long long atomic64_add_return(long long a, atomic64_t *v) -+{ -+ unsigned long flags; -+ long long val; -+ -+ spin_lock_irqsave(&lock, flags); -+ val = v->counter += a; -+ spin_unlock_irqrestore(&lock, flags); -+ return val; -+} -+EXPORT_SYMBOL(atomic64_add_return); -+ -+#endif -+ ---- a/include/linux/compat-3.1.h -+++ b/include/linux/compat-3.1.h -@@ -19,6 +19,18 @@ - .prod_id = { NULL, NULL, (v3), NULL }, \ - .prod_id_hash = { 0, 0, (vh3), 0 }, } - -+/* -+ * In many versions, several architectures do not seem to include an -+ * atomic64_t implementation, and do not include the software emulation from -+ * asm-generic/atomic64_t. -+ * Detect and handle this here. -+ */ -+#include -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,31)) && !defined(ATOMIC64_INIT) && !defined(CONFIG_X86) && !((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,33)) && defined(CONFIG_ARM) && !defined(CONFIG_GENERIC_ATOMIC64)) -+#include -+#endif -+ - #endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(3,1,0)) */ - - #endif /* LINUX_3_1_COMPAT_H */ diff --git a/package/mac80211/patches/050-compat_firmware.patch b/package/mac80211/patches/050-compat_firmware.patch index c51c672139..af7c4fec62 100644 --- a/package/mac80211/patches/050-compat_firmware.patch +++ b/package/mac80211/patches/050-compat_firmware.patch @@ -17,7 +17,7 @@ compat-$(CONFIG_COMPAT_KERNEL_2_6_18) += compat-2.6.18.o --- a/compat/compat_firmware_class.c +++ b/compat/compat_firmware_class.c -@@ -729,19 +729,16 @@ request_firmware_nowait( +@@ -741,19 +741,16 @@ request_firmware_nowait( return 0; } diff --git a/package/mac80211/patches/051-compat_workqueue.patch b/package/mac80211/patches/051-compat_workqueue.patch deleted file mode 100644 index d94507db71..0000000000 --- a/package/mac80211/patches/051-compat_workqueue.patch +++ /dev/null @@ -1,18 +0,0 @@ ---- a/compat/compat-2.6.36.c -+++ b/compat/compat-2.6.36.c -@@ -93,6 +93,8 @@ void compat_usb_scuttle_anchored_urbs(st - } - EXPORT_SYMBOL_GPL(compat_usb_scuttle_anchored_urbs); - -+#endif /* CONFIG_COMPAT_USB_URB_THREAD_FIX */ -+ - struct workqueue_struct *system_nrt_wq __read_mostly; - EXPORT_SYMBOL_GPL(system_nrt_wq); - -@@ -106,6 +108,3 @@ void compat_system_workqueue_destroy() - { - destroy_workqueue(system_nrt_wq); - } -- --#endif /* CONFIG_COMPAT_USB_URB_THREAD_FIX */ -- diff --git a/package/mac80211/patches/060-fix_compat_security.patch b/package/mac80211/patches/060-fix_compat_security.patch new file mode 100644 index 0000000000..1942499913 --- /dev/null +++ b/package/mac80211/patches/060-fix_compat_security.patch @@ -0,0 +1,11 @@ +--- a/include/linux/compat-3.1.h ++++ b/include/linux/compat-3.1.h +@@ -5,6 +5,8 @@ + + #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,1,0)) + ++#include ++ + #define genl_dump_check_consistent(cb, user_hdr, family) + + #define IFF_TX_SKB_SHARING 0x10000 /* The interface supports sharing diff --git a/package/mac80211/patches/070-deactivate_mac80211_tracing.patch b/package/mac80211/patches/070-deactivate_mac80211_tracing.patch new file mode 100644 index 0000000000..feff5eb9a0 --- /dev/null +++ b/package/mac80211/patches/070-deactivate_mac80211_tracing.patch @@ -0,0 +1,44 @@ +Do not activate the mac80211 tracing by default as it does not work with +kernel <= 2.6.32. Compat also includes include/trace/define_trace.h over +include/trace/events/module.h which makes this not compiling any more. + +--- a/net/mac80211/Makefile ++++ b/net/mac80211/Makefile +@@ -24,8 +24,7 @@ mac80211-y := \ + util.o \ + wme.o \ + event.o \ +- chan.o \ +- driver-trace.o ++ chan.o + + mac80211-$(CONFIG_MAC80211_LEDS) += led.o + mac80211-$(CONFIG_MAC80211_DEBUGFS) += \ +@@ -42,6 +41,7 @@ mac80211-$(CONFIG_MAC80211_MESH) += \ + + mac80211-$(CONFIG_PM) += pm.o + ++mac80211-$(CONFIG_MAC80211_DRIVER_API_TRACER) += driver-trace.o + CFLAGS_driver-trace.o := -I$(src) + + # objects for PID algorithm +--- a/net/mac80211/driver-trace.h ++++ b/net/mac80211/driver-trace.h +@@ -5,6 +5,17 @@ + #include + #include "ieee80211_i.h" + ++#if !defined(CONFIG_MAC80211_DRIVER_API_TRACER) || defined(__CHECKER__) ++#undef TRACE_EVENT ++#define TRACE_EVENT(name, proto, ...) \ ++static inline void trace_ ## name(proto) {} ++#undef DECLARE_EVENT_CLASS ++#define DECLARE_EVENT_CLASS(...) ++#undef DEFINE_EVENT ++#define DEFINE_EVENT(evt_class, name, proto, ...) \ ++static inline void trace_ ## name(proto) {} ++#endif ++ + #undef TRACE_SYSTEM + #define TRACE_SYSTEM mac80211 + diff --git a/package/mac80211/patches/100-disable_pcmcia_compat.patch b/package/mac80211/patches/100-disable_pcmcia_compat.patch index 52979ad880..fb5ae7d628 100644 --- a/package/mac80211/patches/100-disable_pcmcia_compat.patch +++ b/package/mac80211/patches/100-disable_pcmcia_compat.patch @@ -51,7 +51,7 @@ #include #include #include -@@ -68,9 +68,9 @@ static inline struct sk_buff *netdev_all +@@ -74,9 +74,9 @@ static inline struct sk_buff *netdev_all return skb; } diff --git a/package/mac80211/patches/110-disable_usb_compat.patch b/package/mac80211/patches/110-disable_usb_compat.patch index 7318cf935d..67a5527939 100644 --- a/package/mac80211/patches/110-disable_usb_compat.patch +++ b/package/mac80211/patches/110-disable_usb_compat.patch @@ -33,7 +33,7 @@ #endif --- a/config.mk +++ b/config.mk -@@ -453,7 +453,7 @@ endif #CONFIG_COMPAT_KERNEL_2_6_29 +@@ -492,7 +492,7 @@ endif #CONFIG_COMPAT_KERNEL_2_6_29 # This activates a threading fix for usb urb. # this is mainline commit: b3e670443b7fb8a2d29831b62b44a039c283e351 # This fix will be included in some stable releases. diff --git a/package/mac80211/patches/120-pr_fmt_warnings.patch b/package/mac80211/patches/120-pr_fmt_warnings.patch index 53add829ba..44c1f3c9c3 100644 --- a/package/mac80211/patches/120-pr_fmt_warnings.patch +++ b/package/mac80211/patches/120-pr_fmt_warnings.patch @@ -1,5 +1,5 @@ ---- a/drivers/net/wireless/iwlegacy/iwl3945-base.c -+++ b/drivers/net/wireless/iwlegacy/iwl3945-base.c +--- a/drivers/net/wireless/iwlegacy/3945-mac.c ++++ b/drivers/net/wireless/iwlegacy/3945-mac.c @@ -27,6 +27,7 @@ * *****************************************************************************/ @@ -78,8 +78,8 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include ---- a/drivers/net/wireless/iwlegacy/iwl4965-base.c -+++ b/drivers/net/wireless/iwlegacy/iwl4965-base.c +--- a/drivers/net/wireless/iwlegacy/4965-mac.c ++++ b/drivers/net/wireless/iwlegacy/4965-mac.c @@ -27,6 +27,7 @@ * *****************************************************************************/ diff --git a/package/mac80211/patches/130-fix_sublevel_check.patch b/package/mac80211/patches/130-fix_sublevel_check.patch index b233311ab1..9dfa90af32 100644 --- a/package/mac80211/patches/130-fix_sublevel_check.patch +++ b/package/mac80211/patches/130-fix_sublevel_check.patch @@ -1,6 +1,6 @@ --- a/config.mk +++ b/config.mk -@@ -20,16 +20,16 @@ COMPAT_LATEST_VERSION = 1 +@@ -20,16 +20,16 @@ COMPAT_LATEST_VERSION = 3 KERNEL_VERSION := $(shell $(MAKE) -C $(KLIB_BUILD) kernelversion | sed -n 's/^\([0-9]\)\..*/\1/p') ifneq ($(KERNEL_VERSION),2) @@ -19,4 +19,4 @@ +COMPAT_VERSIONS := $(shell I=$(COMPAT_LATEST_VERSION); while [ "$$I" -gt $(COMPAT_KERNEL_SUBLEVEL) ]; do echo $$I; I=$$(($$I - 1)); done) $(foreach ver,$(COMPAT_VERSIONS),$(eval CONFIG_COMPAT_KERNEL_3_$(ver)=y)) - ifdef CONFIG_COMPAT_KERNEL_2_6_24 + RHEL_MAJOR := $(shell grep ^RHEL_MAJOR $(KLIB_BUILD)/Makefile | sed -n 's/.*= *\(.*\)/\1/p') diff --git a/package/mac80211/patches/140-mesh_pathtbl_backport.patch b/package/mac80211/patches/140-mesh_pathtbl_backport.patch index 2a3591373d..817060d42a 100644 --- a/package/mac80211/patches/140-mesh_pathtbl_backport.patch +++ b/package/mac80211/patches/140-mesh_pathtbl_backport.patch @@ -1,6 +1,6 @@ --- a/net/mac80211/mesh_pathtbl.c +++ b/net/mac80211/mesh_pathtbl.c -@@ -841,7 +841,6 @@ static void table_flush_by_iface(struct +@@ -826,7 +826,6 @@ static void table_flush_by_iface(struct struct hlist_node *p; int i; diff --git a/package/mac80211/patches/201-ath5k-WAR-for-AR71xx-PCI-bug.patch b/package/mac80211/patches/201-ath5k-WAR-for-AR71xx-PCI-bug.patch index c1f18af080..72274eefe9 100644 --- a/package/mac80211/patches/201-ath5k-WAR-for-AR71xx-PCI-bug.patch +++ b/package/mac80211/patches/201-ath5k-WAR-for-AR71xx-PCI-bug.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/ath/ath5k/initvals.c +++ b/drivers/net/wireless/ath/ath5k/initvals.c -@@ -57,8 +57,14 @@ static const struct ath5k_ini ar5210_ini +@@ -60,8 +60,14 @@ static const struct ath5k_ini ar5210_ini { AR5K_IMR, 0 }, { AR5K_IER, AR5K_IER_DISABLE }, { AR5K_BSR, 0, AR5K_INI_READ }, @@ -17,7 +17,7 @@ { AR5K_RXNOFRM, 8 }, --- a/drivers/net/wireless/ath/ath5k/dma.c +++ b/drivers/net/wireless/ath/ath5k/dma.c -@@ -786,10 +786,18 @@ void ath5k_hw_dma_init(struct ath5k_hw * +@@ -858,10 +858,18 @@ ath5k_hw_dma_init(struct ath5k_hw *ah) * guess we can tweak it and see how it goes ;-) */ if (ah->ah_version != AR5K_AR5210) { diff --git a/package/mac80211/patches/300-pending_work.patch b/package/mac80211/patches/300-pending_work.patch index e86505368d..1b7f41b19a 100644 --- a/package/mac80211/patches/300-pending_work.patch +++ b/package/mac80211/patches/300-pending_work.patch @@ -1,3 +1,59 @@ +--- a/drivers/net/wireless/ath/ath9k/ar9002_calib.c ++++ b/drivers/net/wireless/ath/ath9k/ar9002_calib.c +@@ -203,7 +203,7 @@ static void ar9002_hw_iqcalibrate(struct + i); + + ath_dbg(common, ATH_DBG_CALIBRATE, +- "Orignal: Chn %diq_corr_meas = 0x%08x\n", ++ "Original: Chn %d iq_corr_meas = 0x%08x\n", + i, ah->totalIqCorrMeas[i]); + + iqCorrNeg = 0; +--- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c ++++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c +@@ -226,7 +226,7 @@ static void ar9003_hw_iqcalibrate(struct + i); + + ath_dbg(common, ATH_DBG_CALIBRATE, +- "Orignal: Chn %diq_corr_meas = 0x%08x\n", ++ "Original: Chn %d iq_corr_meas = 0x%08x\n", + i, ah->totalIqCorrMeas[i]); + + iqCorrNeg = 0; +--- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c ++++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c +@@ -808,7 +808,8 @@ void ath9k_htc_ani_work(struct work_stru + } + + /* Verify whether we must check ANI */ +- if ((timestamp - common->ani.checkani_timer) >= ATH_ANI_POLLINTERVAL) { ++ if (ah->config.enable_ani && ++ (timestamp - common->ani.checkani_timer) >= ATH_ANI_POLLINTERVAL) { + aniflag = true; + common->ani.checkani_timer = timestamp; + } +--- a/drivers/net/wireless/ath/ath9k/hw.c ++++ b/drivers/net/wireless/ath/ath9k/hw.c +@@ -504,7 +504,7 @@ static int ath9k_hw_post_init(struct ath + return ecode; + } + +- if (!AR_SREV_9100(ah) && !AR_SREV_9340(ah)) { ++ if (ah->config.enable_ani) { + ath9k_hw_ani_setup(ah); + ath9k_hw_ani_init(ah); + } +@@ -610,6 +610,10 @@ static int __ath9k_hw_init(struct ath_hw + if (!AR_SREV_9300_20_OR_LATER(ah)) + ah->ani_function &= ~ATH9K_ANI_MRC_CCK; + ++ /* disable ANI for 9340 */ ++ if (AR_SREV_9340(ah)) ++ ah->config.enable_ani = false; ++ + ath9k_hw_init_mode_regs(ah); + + if (!ah->is_pciexpress) --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -118,7 +118,7 @@ void ath9k_ps_restore(struct ath_softc * @@ -9,6 +65,15 @@ mode = ATH9K_PM_FULL_SLEEP; else if (sc->ps_enabled && !(sc->ps_flags & (PS_WAIT_FOR_BEACON | +@@ -286,7 +286,7 @@ static bool ath_complete_reset(struct at + ath_start_ani(common); + } + +- if (ath9k_hw_ops(ah)->antdiv_comb_conf_get && sc->ant_rx != 3) { ++ if ((ah->caps.hw_caps & ATH9K_HW_CAP_ANT_DIV_COMB) && sc->ant_rx != 3) { + struct ath_hw_antcomb_conf div_ant_conf; + u8 lna_conf; + @@ -332,7 +332,8 @@ static int ath_reset_internal(struct ath hchan = ah->curchan; } @@ -19,7 +84,48 @@ fastcc = false; if (!ath_prepare_reset(sc, retry_tx, flush)) -@@ -882,82 +883,6 @@ chip_reset: +@@ -561,7 +562,6 @@ void ath_ani_calibrate(unsigned long dat + /* Long calibration runs independently of short calibration. */ + if ((timestamp - common->ani.longcal_timer) >= long_cal_interval) { + longcal = true; +- ath_dbg(common, ATH_DBG_ANI, "longcal @%lu\n", jiffies); + common->ani.longcal_timer = timestamp; + } + +@@ -569,8 +569,6 @@ void ath_ani_calibrate(unsigned long dat + if (!common->ani.caldone) { + if ((timestamp - common->ani.shortcal_timer) >= short_cal_interval) { + shortcal = true; +- ath_dbg(common, ATH_DBG_ANI, +- "shortcal @%lu\n", jiffies); + common->ani.shortcal_timer = timestamp; + common->ani.resetcal_timer = timestamp; + } +@@ -584,8 +582,9 @@ void ath_ani_calibrate(unsigned long dat + } + + /* Verify whether we must check ANI */ +- if ((timestamp - common->ani.checkani_timer) >= +- ah->config.ani_poll_interval) { ++ if (sc->sc_ah->config.enable_ani ++ && (timestamp - common->ani.checkani_timer) >= ++ ah->config.ani_poll_interval) { + aniflag = true; + common->ani.checkani_timer = timestamp; + } +@@ -605,6 +604,11 @@ void ath_ani_calibrate(unsigned long dat + ah->rxchainmask, longcal); + } + ++ ath_dbg(common, ATH_DBG_ANI, ++ "Calibration @%lu finished: %s %s %s, caldone: %s\n", jiffies, ++ longcal ? "long" : "", shortcal ? "short" : "", ++ aniflag ? "ani" : "", common->ani.caldone ? "true" : "false"); ++ + ath9k_ps_restore(sc); + + set_timer: +@@ -886,82 +890,6 @@ chip_reset: #undef SCHED_INTR } @@ -102,7 +208,7 @@ static int ath_reset(struct ath_softc *sc, bool retry_tx) { int r; -@@ -1093,6 +1018,9 @@ static int ath9k_start(struct ieee80211_ +@@ -1097,6 +1025,9 @@ static int ath9k_start(struct ieee80211_ * and then setup of the interrupt mask. */ spin_lock_bh(&sc->sc_pcu_lock); @@ -112,7 +218,7 @@ r = ath9k_hw_reset(ah, init_channel, ah->caldata, false); if (r) { ath_err(common, -@@ -1131,6 +1059,18 @@ static int ath9k_start(struct ieee80211_ +@@ -1138,6 +1069,18 @@ static int ath9k_start(struct ieee80211_ goto mutex_unlock; } @@ -131,7 +237,7 @@ spin_unlock_bh(&sc->sc_pcu_lock); if ((ah->btcoex_hw.scheme != ATH_BTCOEX_CFG_NONE) && -@@ -1176,6 +1116,13 @@ static void ath9k_tx(struct ieee80211_hw +@@ -1183,6 +1126,13 @@ static void ath9k_tx(struct ieee80211_hw } } @@ -145,7 +251,7 @@ if (unlikely(sc->sc_ah->power_mode != ATH9K_PM_AWAKE)) { /* * We are using PS-Poll and mac80211 can request TX while in -@@ -1222,6 +1169,7 @@ static void ath9k_stop(struct ieee80211_ +@@ -1229,6 +1179,7 @@ static void ath9k_stop(struct ieee80211_ struct ath_softc *sc = hw->priv; struct ath_hw *ah = sc->sc_ah; struct ath_common *common = ath9k_hw_common(ah); @@ -153,7 +259,7 @@ mutex_lock(&sc->mutex); -@@ -1252,35 +1200,45 @@ static void ath9k_stop(struct ieee80211_ +@@ -1259,35 +1210,45 @@ static void ath9k_stop(struct ieee80211_ * before setting the invalid flag. */ ath9k_hw_disable_interrupts(ah); @@ -216,7 +322,7 @@ mutex_unlock(&sc->mutex); -@@ -1620,8 +1578,8 @@ static int ath9k_config(struct ieee80211 +@@ -1627,8 +1588,8 @@ static int ath9k_config(struct ieee80211 struct ath_hw *ah = sc->sc_ah; struct ath_common *common = ath9k_hw_common(ah); struct ieee80211_conf *conf = &hw->conf; @@ -226,7 +332,7 @@ mutex_lock(&sc->mutex); /* -@@ -1632,13 +1590,8 @@ static int ath9k_config(struct ieee80211 +@@ -1639,13 +1600,8 @@ static int ath9k_config(struct ieee80211 */ if (changed & IEEE80211_CONF_CHANGE_IDLE) { sc->ps_idle = !!(conf->flags & IEEE80211_CONF_IDLE); @@ -242,7 +348,7 @@ } /* -@@ -1745,18 +1698,12 @@ static int ath9k_config(struct ieee80211 +@@ -1752,18 +1708,12 @@ static int ath9k_config(struct ieee80211 ath_dbg(common, ATH_DBG_CONFIG, "Set power: %d\n", conf->power_level); sc->config.txpowlimit = 2 * conf->power_level; @@ -262,7 +368,7 @@ return 0; } -@@ -2324,9 +2271,6 @@ static void ath9k_flush(struct ieee80211 +@@ -2331,9 +2281,6 @@ static void ath9k_flush(struct ieee80211 return; } @@ -272,7 +378,7 @@ for (j = 0; j < timeout; j++) { bool npend = false; -@@ -2344,21 +2288,22 @@ static void ath9k_flush(struct ieee80211 +@@ -2351,21 +2298,22 @@ static void ath9k_flush(struct ieee80211 } if (!npend) @@ -346,36 +452,7 @@ --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c -@@ -179,6 +179,11 @@ static void ath_tx_flush_tid(struct ath_ - spin_lock_bh(&txq->axq_lock); - } - -+ if (tid->baw_head == tid->baw_tail) { -+ tid->state &= ~AGGR_ADDBA_COMPLETE; -+ tid->state &= ~AGGR_CLEANUP; -+ } -+ - spin_unlock_bh(&txq->axq_lock); - } - -@@ -556,15 +561,9 @@ static void ath_tx_complete_aggr(struct - spin_unlock_bh(&txq->axq_lock); - } - -- if (tid->state & AGGR_CLEANUP) { -+ if (tid->state & AGGR_CLEANUP) - ath_tx_flush_tid(sc, tid); - -- if (tid->baw_head == tid->baw_tail) { -- tid->state &= ~AGGR_ADDBA_COMPLETE; -- tid->state &= ~AGGR_CLEANUP; -- } -- } -- - rcu_read_unlock(); - - if (needreset) { -@@ -1955,7 +1954,7 @@ static void ath_tx_complete(struct ath_s +@@ -1954,7 +1954,7 @@ static void ath_tx_complete(struct ath_s skb_pull(skb, padsize); } @@ -384,9 +461,23 @@ sc->ps_flags &= ~PS_WAIT_FOR_TX_ACK; ath_dbg(common, ATH_DBG_PS, "Going back to sleep after having received TX status (0x%lx)\n", +--- a/include/linux/nl80211.h ++++ b/include/linux/nl80211.h +@@ -2785,9 +2785,11 @@ enum nl80211_ap_sme_features { + * @NL80211_FEATURE_SK_TX_STATUS: This driver supports reflecting back + * TX status to the socket error queue when requested with the + * socket option. ++ * @NL80211_FEATURE_HT_IBSS: This driver supports IBSS with HT datarates. + */ + enum nl80211_feature_flags { + NL80211_FEATURE_SK_TX_STATUS = 1 << 0, ++ NL80211_FEATURE_HT_IBSS = 1 << 1, + }; + + /** --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h -@@ -1130,6 +1130,7 @@ struct cfg80211_ibss_params { +@@ -1149,6 +1149,7 @@ struct cfg80211_ibss_params { u8 *ssid; u8 *bssid; struct ieee80211_channel *channel; @@ -394,39 +485,48 @@ u8 *ie; u8 ssid_len, ie_len; u16 beacon_interval; -@@ -3292,6 +3293,16 @@ void cfg80211_report_obss_beacon(struct +@@ -3270,6 +3271,16 @@ void cfg80211_report_obss_beacon(struct const u8 *frame, size_t len, int freq, gfp_t gfp); -+/** -+ * cfg80211_can_use_ext_chan - test if ht40 on extension channel can be used ++/* ++ * cfg80211_can_beacon_sec_chan - test if ht40 on extension channel can be used + * @wiphy: the wiphy + * @chan: main channel + * @channel_type: HT mode + */ -+bool cfg80211_can_beacon_sec_chan(struct wiphy *wiphy, -+ struct ieee80211_channel *chan, -+ enum nl80211_channel_type channel_type); ++int cfg80211_can_beacon_sec_chan(struct wiphy *wiphy, ++ struct ieee80211_channel *chan, ++ enum nl80211_channel_type channel_type); + /* Logging, debugging and troubleshooting/diagnostic helpers. */ /* wiphy_printk helpers, similar to dev_printk */ --- a/net/mac80211/agg-rx.c +++ b/net/mac80211/agg-rx.c -@@ -182,6 +182,10 @@ static void ieee80211_send_addba_resp(st +@@ -185,6 +185,10 @@ static void ieee80211_send_addba_resp(st memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN); else if (sdata->vif.type == NL80211_IFTYPE_STATION) memcpy(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN); -+ else if (sdata->vif.type == NL80211_IFTYPE_WDS) -+ memcpy(mgmt->bssid, da, ETH_ALEN); + else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) + memcpy(mgmt->bssid, sdata->u.ibss.bssid, ETH_ALEN); ++ else if (sdata->vif.type == NL80211_IFTYPE_WDS) ++ memcpy(mgmt->bssid, da, ETH_ALEN); mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ACTION); --- a/net/mac80211/agg-tx.c +++ b/net/mac80211/agg-tx.c -@@ -79,10 +79,13 @@ static void ieee80211_send_addba_request +@@ -55,6 +55,8 @@ + * @ampdu_action function will be called with the action + * %IEEE80211_AMPDU_TX_STOP. In this case, the call must not fail, + * and the driver must later call ieee80211_stop_tx_ba_cb_irqsafe(). ++ * Note that the sta can get destroyed before the BA tear down is ++ * complete. + */ + + static void ieee80211_send_addba_request(struct ieee80211_sub_if_data *sdata, +@@ -79,10 +81,13 @@ static void ieee80211_send_addba_request memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN); if (sdata->vif.type == NL80211_IFTYPE_AP || sdata->vif.type == NL80211_IFTYPE_AP_VLAN || @@ -441,28 +541,184 @@ mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ACTION); -@@ -394,7 +397,9 @@ int ieee80211_start_tx_ba_session(struct +@@ -319,6 +324,38 @@ ieee80211_wake_queue_agg(struct ieee8021 + __release(agg_queue); + } + ++/* ++ * splice packets from the STA's pending to the local pending, ++ * requires a call to ieee80211_agg_splice_finish later ++ */ ++static void __acquires(agg_queue) ++ieee80211_agg_splice_packets(struct ieee80211_local *local, ++ struct tid_ampdu_tx *tid_tx, u16 tid) ++{ ++ int queue = ieee80211_ac_from_tid(tid); ++ unsigned long flags; ++ ++ ieee80211_stop_queue_agg(local, tid); ++ ++ if (WARN(!tid_tx, "TID %d gone but expected when splicing aggregates" ++ " from the pending queue\n", tid)) ++ return; ++ ++ if (!skb_queue_empty(&tid_tx->pending)) { ++ spin_lock_irqsave(&local->queue_stop_reason_lock, flags); ++ /* copy over remaining packets */ ++ skb_queue_splice_tail_init(&tid_tx->pending, ++ &local->pending[queue]); ++ spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); ++ } ++} ++ ++static void __releases(agg_queue) ++ieee80211_agg_splice_finish(struct ieee80211_local *local, u16 tid) ++{ ++ ieee80211_wake_queue_agg(local, tid); ++} ++ + void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid) + { + struct tid_ampdu_tx *tid_tx; +@@ -330,19 +367,17 @@ void ieee80211_tx_ba_session_handle_star + tid_tx = rcu_dereference_protected_tid_tx(sta, tid); + + /* +- * While we're asking the driver about the aggregation, +- * stop the AC queue so that we don't have to worry +- * about frames that came in while we were doing that, +- * which would require us to put them to the AC pending +- * afterwards which just makes the code more complex. ++ * Start queuing up packets for this aggregation session. ++ * We're going to release them once the driver is OK with ++ * that. + */ +- ieee80211_stop_queue_agg(local, tid); +- + clear_bit(HT_AGG_STATE_WANT_START, &tid_tx->state); + + /* +- * make sure no packets are being processed to get +- * valid starting sequence number ++ * Make sure no packets are being processed. This ensures that ++ * we have a valid starting sequence number and that in-flight ++ * packets have been flushed out and no packets for this TID ++ * will go into the driver during the ampdu_action call. + */ + synchronize_net(); + +@@ -356,10 +391,11 @@ void ieee80211_tx_ba_session_handle_star + " tid %d\n", tid); + #endif + spin_lock_bh(&sta->lock); ++ ieee80211_agg_splice_packets(local, tid_tx, tid); + ieee80211_assign_tid_tx(sta, tid, NULL); ++ ieee80211_agg_splice_finish(local, tid); + spin_unlock_bh(&sta->lock); + +- ieee80211_wake_queue_agg(local, tid); + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,40)) + kfree_rcu(tid_tx, rcu_head); + #else +@@ -368,9 +404,6 @@ void ieee80211_tx_ba_session_handle_star + return; + } + +- /* we can take packets again now */ +- ieee80211_wake_queue_agg(local, tid); +- + /* activate the timer for the recipient's addBA response */ + mod_timer(&tid_tx->addba_resp_timer, jiffies + ADDBA_RESP_INTERVAL); + #ifdef CONFIG_MAC80211_HT_DEBUG +@@ -437,7 +470,9 @@ int ieee80211_start_tx_ba_session(struct if (sdata->vif.type != NL80211_IFTYPE_STATION && sdata->vif.type != NL80211_IFTYPE_MESH_POINT && sdata->vif.type != NL80211_IFTYPE_AP_VLAN && - sdata->vif.type != NL80211_IFTYPE_AP) + sdata->vif.type != NL80211_IFTYPE_AP && -+ sdata->vif.type != NL80211_IFTYPE_ADHOC && -+ sdata->vif.type != NL80211_IFTYPE_WDS) ++ sdata->vif.type != NL80211_IFTYPE_WDS && ++ sdata->vif.type != NL80211_IFTYPE_ADHOC) return -EINVAL; if (test_sta_flag(sta, WLAN_STA_BLOCK_BA)) { +@@ -448,6 +483,27 @@ int ieee80211_start_tx_ba_session(struct + return -EINVAL; + } + ++ /* ++ * 802.11n-2009 11.5.1.1: If the initiating STA is an HT STA, is a ++ * member of an IBSS, and has no other existing Block Ack agreement ++ * with the recipient STA, then the initiating STA shall transmit a ++ * Probe Request frame to the recipient STA and shall not transmit an ++ * ADDBA Request frame unless it receives a Probe Response frame ++ * from the recipient within dot11ADDBAFailureTimeout. ++ * ++ * The probe request mechanism for ADDBA is currently not implemented, ++ * but we only build up Block Ack session with HT STAs. This information ++ * is set when we receive a bss info from a probe response or a beacon. ++ */ ++ if (sta->sdata->vif.type == NL80211_IFTYPE_ADHOC && ++ !sta->sta.ht_cap.ht_supported) { ++#ifdef CONFIG_MAC80211_HT_DEBUG ++ printk(KERN_DEBUG "BA request denied - IBSS STA %pM" ++ "does not advertise HT support\n", pubsta->addr); ++#endif /* CONFIG_MAC80211_HT_DEBUG */ ++ return -EINVAL; ++ } ++ + spin_lock_bh(&sta->lock); + + /* we have tried too many times, receiver does not want A-MPDU */ +@@ -508,38 +564,6 @@ int ieee80211_start_tx_ba_session(struct + } + EXPORT_SYMBOL(ieee80211_start_tx_ba_session); + +-/* +- * splice packets from the STA's pending to the local pending, +- * requires a call to ieee80211_agg_splice_finish later +- */ +-static void __acquires(agg_queue) +-ieee80211_agg_splice_packets(struct ieee80211_local *local, +- struct tid_ampdu_tx *tid_tx, u16 tid) +-{ +- int queue = ieee80211_ac_from_tid(tid); +- unsigned long flags; +- +- ieee80211_stop_queue_agg(local, tid); +- +- if (WARN(!tid_tx, "TID %d gone but expected when splicing aggregates" +- " from the pending queue\n", tid)) +- return; +- +- if (!skb_queue_empty(&tid_tx->pending)) { +- spin_lock_irqsave(&local->queue_stop_reason_lock, flags); +- /* copy over remaining packets */ +- skb_queue_splice_tail_init(&tid_tx->pending, +- &local->pending[queue]); +- spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); +- } +-} +- +-static void __releases(agg_queue) +-ieee80211_agg_splice_finish(struct ieee80211_local *local, u16 tid) +-{ +- ieee80211_wake_queue_agg(local, tid); +-} +- + static void ieee80211_agg_tx_operational(struct ieee80211_local *local, + struct sta_info *sta, u16 tid) + { --- a/net/mac80211/debugfs_sta.c +++ b/net/mac80211/debugfs_sta.c @@ -63,11 +63,11 @@ static ssize_t sta_flags_read(struct fil test_sta_flag(sta, WLAN_STA_##flg) ? #flg "\n" : "" int res = scnprintf(buf, sizeof(buf), -- "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", -+ "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", +- "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", ++ "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", TEST(AUTH), TEST(ASSOC), TEST(PS_STA), TEST(PS_DRIVER), TEST(AUTHORIZED), - TEST(SHORT_PREAMBLE), TEST(ASSOC_AP), + TEST(SHORT_PREAMBLE), - TEST(WME), TEST(WDS), TEST(CLEAR_PS_FILT), + TEST(WME), TEST(CLEAR_PS_FILT), TEST(MFP), TEST(BLOCK_BA), TEST(PSPOLL), @@ -470,7 +726,18 @@ TEST(TDLS_PEER_AUTH)); --- a/net/mac80211/ht.c +++ b/net/mac80211/ht.c -@@ -201,6 +201,8 @@ void ieee80211_send_delba(struct ieee802 +@@ -47,7 +47,9 @@ void ieee80211_apply_htcap_overrides(str + int i; + + if (sdata->vif.type != NL80211_IFTYPE_STATION) { +- WARN_ON_ONCE(sdata->vif.type != NL80211_IFTYPE_STATION); ++ /* AP interfaces call this code when adding new stations, ++ * so just silently ignore non station interfaces. ++ */ + return; + } + +@@ -282,6 +284,8 @@ void ieee80211_send_delba(struct ieee802 memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN); else if (sdata->vif.type == NL80211_IFTYPE_STATION) memcpy(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN); @@ -508,7 +775,7 @@ ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); sband = local->hw.wiphy->bands[chan->band]; -@@ -172,6 +181,18 @@ static void __ieee80211_sta_join_ibss(st +@@ -172,6 +181,19 @@ static void __ieee80211_sta_join_ibss(st memcpy(skb_put(skb, ifibss->ie_len), ifibss->ie, ifibss->ie_len); @@ -517,7 +784,8 @@ + pos = skb_put(skb, 4 + + sizeof(struct ieee80211_ht_cap) + + sizeof(struct ieee80211_ht_info)); -+ pos = ieee80211_ie_build_ht_cap(pos, sband, sband->ht_cap.cap); ++ pos = ieee80211_ie_build_ht_cap(pos, &sband->ht_cap, ++ sband->ht_cap.cap); + pos = ieee80211_ie_build_ht_info(pos, + &sband->ht_cap, + chan, @@ -527,7 +795,7 @@ if (local->hw.queues >= 4) { pos = skb_put(skb, 9); *pos++ = WLAN_EID_VENDOR_SPECIFIC; -@@ -195,6 +216,7 @@ static void __ieee80211_sta_join_ibss(st +@@ -195,6 +217,7 @@ static void __ieee80211_sta_join_ibss(st bss_change |= BSS_CHANGED_BEACON; bss_change |= BSS_CHANGED_BEACON_ENABLED; bss_change |= BSS_CHANGED_BASIC_RATES; @@ -535,72 +803,69 @@ bss_change |= BSS_CHANGED_IBSS; sdata->vif.bss_conf.ibss_joined = true; ieee80211_bss_info_change_notify(sdata, bss_change); -@@ -268,6 +290,7 @@ static void ieee80211_rx_bss_info(struct +@@ -268,6 +291,8 @@ static void ieee80211_rx_bss_info(struct u64 beacon_timestamp, rx_timestamp; u32 supp_rates = 0; enum ieee80211_band band = rx_status->band; + struct ieee80211_supported_band *sband = local->hw.wiphy->bands[band]; ++ bool rates_updated = false; if (elems->ds_params && elems->ds_params_len == 1) freq = ieee80211_channel_to_frequency(elems->ds_params[0], -@@ -277,7 +300,10 @@ static void ieee80211_rx_bss_info(struct - - channel = ieee80211_get_channel(local->hw.wiphy, freq); - -- if (!channel || channel->flags & IEEE80211_CHAN_DISABLED) -+ if (!channel || -+ channel->flags & (IEEE80211_CHAN_DISABLED || -+ IEEE80211_CHAN_NO_IBSS || -+ IEEE80211_CHAN_RADAR)) - return; - - if (sdata->vif.type == NL80211_IFTYPE_ADHOC && -@@ -315,8 +341,41 @@ static void ieee80211_rx_bss_info(struct - GFP_ATOMIC); - } - -- if (sta && elems->wmm_info) -- set_sta_flag(sta, WLAN_STA_WME); -+ if (sta) { -+ if (elems->wmm_info) -+ set_sta_flag(sta, WLAN_STA_WME); -+ +@@ -307,7 +332,7 @@ static void ieee80211_rx_bss_info(struct + prev_rates, + sta->sta.supp_rates[band]); + #endif +- rate_control_rate_init(sta); ++ rates_updated = true; + } + } else + sta = ieee80211_ibss_add_sta(sdata, mgmt->bssid, +@@ -318,6 +343,39 @@ static void ieee80211_rx_bss_info(struct + if (sta && elems->wmm_info) + set_sta_flag(sta, WLAN_STA_WME); + ++ if (sta && elems->ht_info_elem && elems->ht_cap_elem && ++ sdata->u.ibss.channel_type != NL80211_CHAN_NO_HT) { + /* we both use HT */ -+ if (elems->ht_info_elem && elems->ht_cap_elem && -+ sdata->u.ibss.channel_type) { -+ enum nl80211_channel_type channel_type = -+ ieee80211_ht_info_to_channel_type( -+ elems->ht_info_elem); -+ struct ieee80211_sta_ht_cap sta_ht_cap_new; -+ -+ /* -+ * fall back to HT20 if we don't use or use -+ * the other extension channel -+ */ -+ if (channel_type > NL80211_CHAN_HT20 && -+ channel_type != sdata->u.ibss.channel_type) -+ channel_type = NL80211_CHAN_HT20; -+ -+ ieee80211_ht_cap_ie_to_sta_ht_cap(sband, -+ elems->ht_cap_elem, -+ &sta_ht_cap_new); -+ if (memcmp(&sta->sta.ht_cap, &sta_ht_cap_new, -+ sizeof(sta_ht_cap_new))) { -+ memcpy(&sta->sta.ht_cap, -+ &sta_ht_cap_new, -+ sizeof(sta_ht_cap_new)); -+ rate_control_rate_update(local, sband, -+ sta, -+ IEEE80211_RC_HT_CHANGED, -+ channel_type); -+ } ++ struct ieee80211_sta_ht_cap sta_ht_cap_new; ++ enum nl80211_channel_type channel_type = ++ ieee80211_ht_info_to_channel_type( ++ elems->ht_info_elem); ++ ++ ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband, ++ elems->ht_cap_elem, ++ &sta_ht_cap_new); ++ ++ /* ++ * fall back to HT20 if we don't use or use ++ * the other extension channel ++ */ ++ if ((channel_type == NL80211_CHAN_HT40MINUS || ++ channel_type == NL80211_CHAN_HT40PLUS) && ++ channel_type != sdata->u.ibss.channel_type) ++ sta_ht_cap_new.cap &= ++ ~IEEE80211_HT_CAP_SUP_WIDTH_20_40; ++ ++ if (memcmp(&sta->sta.ht_cap, &sta_ht_cap_new, ++ sizeof(sta_ht_cap_new))) { ++ memcpy(&sta->sta.ht_cap, &sta_ht_cap_new, ++ sizeof(sta_ht_cap_new)); ++ rates_updated = true; + } + } - ++ ++ if (sta && rates_updated) ++ rate_control_rate_init(sta); ++ rcu_read_unlock(); } -@@ -898,10 +957,15 @@ int ieee80211_ibss_join(struct ieee80211 + +@@ -896,12 +954,18 @@ int ieee80211_ibss_join(struct ieee80211 + struct cfg80211_ibss_params *params) + { struct sk_buff *skb; ++ u32 changed = 0; skb = dev_alloc_skb(sdata->local->hw.extra_tx_headroom + - 36 /* bitrates */ + @@ -637,9 +902,33 @@ } if (params->ie) { +@@ -951,6 +1017,23 @@ int ieee80211_ibss_join(struct ieee80211 + ieee80211_recalc_idle(sdata->local); + mutex_unlock(&sdata->local->mtx); + ++ /* ++ * 802.11n-2009 9.13.3.1: In an IBSS, the HT Protection field is ++ * reserved, but an HT STA shall protect HT transmissions as though ++ * the HT Protection field were set to non-HT mixed mode. ++ * ++ * In an IBSS, the RIFS Mode field of the HT Operation element is ++ * also reserved, but an HT STA shall operate as though this field ++ * were set to 1. ++ */ ++ ++ sdata->vif.bss_conf.ht_operation_mode |= ++ IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED ++ | IEEE80211_HT_PARAM_RIFS_MODE; ++ ++ changed |= BSS_CHANGED_HT; ++ ieee80211_bss_info_change_notify(sdata, changed); ++ + ieee80211_queue_work(&sdata->local->hw, &sdata->work); + + return 0; --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h -@@ -470,6 +470,7 @@ struct ieee80211_if_ibss { +@@ -474,6 +474,7 @@ struct ieee80211_if_ibss { u8 ssid_len, ie_len; u8 *ie; struct ieee80211_channel *channel; @@ -695,7 +984,7 @@ err_stop: if (!local->open_count) drv_stop(local); -@@ -732,6 +709,70 @@ static void ieee80211_if_setup(struct ne +@@ -719,6 +696,70 @@ static void ieee80211_if_setup(struct ne dev->destructor = free_netdev; } @@ -748,7 +1037,7 @@ + sta->sta.supp_rates[local->hw.conf.channel->band] = rates; + + if (elems.ht_cap_elem) -+ ieee80211_ht_cap_ie_to_sta_ht_cap(sband, ++ ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband, + elems.ht_cap_elem, &sta->sta.ht_cap); + + if (elems.wmm_param) @@ -766,7 +1055,7 @@ static void ieee80211_iface_work(struct work_struct *work) { struct ieee80211_sub_if_data *sdata = -@@ -836,6 +877,9 @@ static void ieee80211_iface_work(struct +@@ -823,6 +864,9 @@ static void ieee80211_iface_work(struct break; ieee80211_mesh_rx_queued_mgmt(sdata, skb); break; @@ -776,85 +1065,32 @@ default: WARN(1, "frame for unexpected interface type"); break; ---- a/net/mac80211/mlme.c -+++ b/net/mac80211/mlme.c -@@ -1359,9 +1359,6 @@ static void __ieee80211_connection_loss( - ieee80211_set_disassoc(sdata, true, true); - mutex_unlock(&ifmgd->mtx); - -- mutex_lock(&local->mtx); -- ieee80211_recalc_idle(local); -- mutex_unlock(&local->mtx); - /* - * must be outside lock due to cfg80211, - * but that's not a problem. -@@ -1370,6 +1367,10 @@ static void __ieee80211_connection_loss( - IEEE80211_STYPE_DEAUTH, - WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY, - NULL, true); -+ -+ mutex_lock(&local->mtx); -+ ieee80211_recalc_idle(local); -+ mutex_unlock(&local->mtx); - } - - void ieee80211_beacon_connection_loss_work(struct work_struct *work) -@@ -2136,9 +2137,6 @@ static void ieee80211_sta_connection_los - - ieee80211_set_disassoc(sdata, true, true); - mutex_unlock(&ifmgd->mtx); -- mutex_lock(&local->mtx); -- ieee80211_recalc_idle(local); -- mutex_unlock(&local->mtx); - /* - * must be outside lock due to cfg80211, - * but that's not a problem. -@@ -2146,6 +2144,11 @@ static void ieee80211_sta_connection_los - ieee80211_send_deauth_disassoc(sdata, bssid, - IEEE80211_STYPE_DEAUTH, reason, - NULL, true); -+ -+ mutex_lock(&local->mtx); -+ ieee80211_recalc_idle(local); -+ mutex_unlock(&local->mtx); -+ - mutex_lock(&ifmgd->mtx); - } - ---- a/net/mac80211/offchannel.c -+++ b/net/mac80211/offchannel.c -@@ -212,8 +212,6 @@ static void ieee80211_hw_roc_start(struc - return; - } - -- ieee80211_recalc_idle(local); -- - if (local->hw_roc_skb) { - sdata = IEEE80211_DEV_TO_SUB_IF(local->hw_roc_dev); - ieee80211_tx_skb(sdata, local->hw_roc_skb); -@@ -227,6 +225,8 @@ static void ieee80211_hw_roc_start(struc - GFP_KERNEL); - } - -+ ieee80211_recalc_idle(local); -+ - mutex_unlock(&local->mtx); - } - +--- a/net/mac80211/main.c ++++ b/net/mac80211/main.c +@@ -574,7 +574,8 @@ struct ieee80211_hw *ieee80211_alloc_hw( + WIPHY_FLAG_OFFCHAN_TX | + WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL; + +- wiphy->features = NL80211_FEATURE_SK_TX_STATUS; ++ wiphy->features = NL80211_FEATURE_SK_TX_STATUS | ++ NL80211_FEATURE_HT_IBSS; + + if (!ops->set_key) + wiphy->flags |= WIPHY_FLAG_IBSS_RSN; --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c -@@ -2250,7 +2250,9 @@ ieee80211_rx_h_action(struct ieee80211_r +@@ -2237,7 +2237,9 @@ ieee80211_rx_h_action(struct ieee80211_r if (sdata->vif.type != NL80211_IFTYPE_STATION && sdata->vif.type != NL80211_IFTYPE_MESH_POINT && sdata->vif.type != NL80211_IFTYPE_AP_VLAN && - sdata->vif.type != NL80211_IFTYPE_AP) + sdata->vif.type != NL80211_IFTYPE_AP && -+ sdata->vif.type != NL80211_IFTYPE_ADHOC && -+ sdata->vif.type != NL80211_IFTYPE_WDS) ++ sdata->vif.type != NL80211_IFTYPE_WDS && ++ sdata->vif.type != NL80211_IFTYPE_ADHOC) break; /* verify action_code is present */ -@@ -2465,13 +2467,14 @@ ieee80211_rx_h_mgmt(struct ieee80211_rx_ +@@ -2452,13 +2454,14 @@ ieee80211_rx_h_mgmt(struct ieee80211_rx_ if (!ieee80211_vif_is_mesh(&sdata->vif) && sdata->vif.type != NL80211_IFTYPE_ADHOC && @@ -871,7 +1107,26 @@ break; case cpu_to_le16(IEEE80211_STYPE_DEAUTH): case cpu_to_le16(IEEE80211_STYPE_DISASSOC): -@@ -2818,10 +2821,16 @@ static int prepare_for_handlers(struct i +@@ -2796,19 +2799,32 @@ static int prepare_for_handlers(struct i + return 0; + } else if (!ieee80211_bssid_match(bssid, + sdata->vif.addr)) { ++ /* ++ * Accept public action frames even when the ++ * BSSID doesn't match, this is used for P2P ++ * and location updates. Note that mac80211 ++ * itself never looks at these frames. ++ */ + if (!(status->rx_flags & IEEE80211_RX_IN_SCAN) && +- !ieee80211_is_beacon(hdr->frame_control) && +- !(ieee80211_is_action(hdr->frame_control) && +- sdata->vif.p2p)) ++ ieee80211_is_public_action(hdr, skb->len)) ++ return 1; ++ if (!(status->rx_flags & IEEE80211_RX_IN_SCAN) && ++ !ieee80211_is_beacon(hdr->frame_control)) + return 0; + status->rx_flags &= ~IEEE80211_RX_RA_MATCH; } break; case NL80211_IFTYPE_WDS: @@ -892,38 +1147,60 @@ /* should never get here */ --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h -@@ -32,7 +32,6 @@ +@@ -31,7 +31,6 @@ + * @WLAN_STA_SHORT_PREAMBLE: Station is capable of receiving short-preamble * frames. - * @WLAN_STA_ASSOC_AP: We're associated to that station, it is an AP. * @WLAN_STA_WME: Station is a QoS-STA. - * @WLAN_STA_WDS: Station is one of our WDS peers. * @WLAN_STA_CLEAR_PS_FILT: Clear PS filter in hardware (using the * IEEE80211_TX_CTL_CLEAR_PS_FILT control flag) when the next * frame to this station is transmitted. -@@ -62,7 +61,6 @@ enum ieee80211_sta_info_flags { +@@ -60,7 +59,6 @@ enum ieee80211_sta_info_flags { + WLAN_STA_AUTHORIZED, WLAN_STA_SHORT_PREAMBLE, - WLAN_STA_ASSOC_AP, WLAN_STA_WME, - WLAN_STA_WDS, WLAN_STA_CLEAR_PS_FILT, WLAN_STA_MFP, WLAN_STA_BLOCK_BA, +--- a/net/mac80211/util.c ++++ b/net/mac80211/util.c +@@ -1612,6 +1612,11 @@ u8 *ieee80211_ie_build_ht_info(u8 *pos, + } + if (ht_cap->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) + ht_info->ht_param |= IEEE80211_HT_PARAM_CHAN_WIDTH_ANY; ++ ++ /* ++ * Note: According to 802.11n-2009 9.13.3.1, HT Protection field and ++ * RIFS Mode are reserved in IBSS mode, therefore keep them at 0 ++ */ + ht_info->operation_mode = 0x0000; + ht_info->stbc_param = 0x0000; + --- a/net/wireless/chan.c +++ b/net/wireless/chan.c -@@ -44,9 +44,9 @@ rdev_freq_to_chan(struct cfg80211_regist +@@ -6,6 +6,7 @@ + * Copyright 2009 Johannes Berg + */ + ++#include + #include + #include "core.h" + +@@ -44,9 +45,9 @@ rdev_freq_to_chan(struct cfg80211_regist return chan; } -static bool can_beacon_sec_chan(struct wiphy *wiphy, - struct ieee80211_channel *chan, - enum nl80211_channel_type channel_type) -+bool cfg80211_can_beacon_sec_chan(struct wiphy *wiphy, ++int cfg80211_can_beacon_sec_chan(struct wiphy *wiphy, + struct ieee80211_channel *chan, + enum nl80211_channel_type channel_type) { struct ieee80211_channel *sec_chan; int diff; -@@ -75,6 +75,7 @@ static bool can_beacon_sec_chan(struct w +@@ -75,6 +76,7 @@ static bool can_beacon_sec_chan(struct w return true; } @@ -931,7 +1208,7 @@ int cfg80211_set_freq(struct cfg80211_registered_device *rdev, struct wireless_dev *wdev, int freq, -@@ -109,8 +110,8 @@ int cfg80211_set_freq(struct cfg80211_re +@@ -109,8 +111,8 @@ int cfg80211_set_freq(struct cfg80211_re switch (channel_type) { case NL80211_CHAN_HT40PLUS: case NL80211_CHAN_HT40MINUS: @@ -944,7 +1221,7 @@ "allowed to initiate communication\n"); --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c -@@ -4604,13 +4604,34 @@ static int nl80211_join_ibss(struct sk_b +@@ -4684,13 +4684,41 @@ static int nl80211_join_ibss(struct sk_b ibss.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]); } @@ -955,8 +1232,16 @@ + + channel_type = nla_get_u32( + info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]); -+ if (channel_type > NL80211_CHAN_HT40PLUS) ++ if (channel_type != NL80211_CHAN_NO_HT && ++ channel_type != NL80211_CHAN_HT20 && ++ channel_type != NL80211_CHAN_HT40MINUS && ++ channel_type != NL80211_CHAN_HT40PLUS) ++ return -EINVAL; ++ ++ if (channel_type != NL80211_CHAN_NO_HT && ++ !(wiphy->features & NL80211_FEATURE_HT_IBSS)) + return -EINVAL; ++ + ibss.channel_type = channel_type; + } else { + ibss.channel_type = NL80211_CHAN_NO_HT; @@ -966,7 +1251,6 @@ + nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]), + ibss.channel_type); if (!ibss.channel || -+ ibss.channel->flags & IEEE80211_CHAN_RADAR || ibss.channel->flags & IEEE80211_CHAN_NO_IBSS || ibss.channel->flags & IEEE80211_CHAN_DISABLED) return -EINVAL; @@ -981,3 +1265,85 @@ ibss.channel_fixed = !!info->attrs[NL80211_ATTR_FREQ_FIXED]; ibss.privacy = !!info->attrs[NL80211_ATTR_PRIVACY]; +--- a/include/linux/ieee80211.h ++++ b/include/linux/ieee80211.h +@@ -1695,6 +1695,23 @@ static inline bool ieee80211_is_robust_m + } + + /** ++ * ieee80211_is_public_action - check if frame is a public action frame ++ * @hdr: the frame ++ * @len: length of the frame ++ */ ++static inline bool ieee80211_is_public_action(struct ieee80211_hdr *hdr, ++ size_t len) ++{ ++ struct ieee80211_mgmt *mgmt = (void *)hdr; ++ ++ if (len < 25) ++ return false; ++ if (!ieee80211_is_action(hdr->frame_control)) ++ return false; ++ return mgmt->u.action.category == WLAN_CATEGORY_PUBLIC; ++} ++ ++/** + * ieee80211_fhss_chan_to_freq - get channel frequency + * @channel: the FHSS channel + * +--- a/net/mac80211/tx.c ++++ b/net/mac80211/tx.c +@@ -1332,8 +1332,11 @@ static int invoke_tx_handlers(struct iee + if (!(tx->local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL)) + CALL_TXH(ieee80211_tx_h_rate_ctrl); + +- if (unlikely(info->flags & IEEE80211_TX_INTFL_RETRANSMISSION)) ++ if (unlikely(info->flags & IEEE80211_TX_INTFL_RETRANSMISSION)) { ++ __skb_queue_tail(&tx->skbs, tx->skb); ++ tx->skb = NULL; + goto txh_done; ++ } + + CALL_TXH(ieee80211_tx_h_michael_mic_add); + CALL_TXH(ieee80211_tx_h_sequence); +--- a/net/mac80211/sta_info.c ++++ b/net/mac80211/sta_info.c +@@ -851,6 +851,7 @@ static int __must_check __sta_info_destr + struct ieee80211_sub_if_data *sdata; + unsigned long flags; + int ret, i, ac; ++ struct tid_ampdu_tx *tid_tx; + + might_sleep(); + +@@ -949,6 +950,30 @@ static int __must_check __sta_info_destr + } + #endif + ++ /* There could be some memory leaks because of ampdu tx pending queue ++ * not being freed before destroying the station info. ++ * ++ * Make sure that such queues are purged before freeing the station ++ * info. ++ * TODO: We have to somehow postpone the full destruction ++ * until the aggregation stop completes. Refer ++ * http://thread.gmane.org/gmane.linux.kernel.wireless.general/81936 ++ */ ++ for (i = 0; i < STA_TID_NUM; i++) { ++ if (!sta->ampdu_mlme.tid_tx[i]) ++ continue; ++ tid_tx = sta->ampdu_mlme.tid_tx[i]; ++ if (skb_queue_len(&tid_tx->pending)) { ++#ifdef CONFIG_MAC80211_HT_DEBUG ++ wiphy_debug(local->hw.wiphy, "TX A-MPDU purging %d " ++ "packets for tid=%d\n", ++ skb_queue_len(&tid_tx->pending), i); ++#endif /* CONFIG_MAC80211_HT_DEBUG */ ++ __skb_queue_purge(&tid_tx->pending); ++ } ++ kfree_rcu(tid_tx, rcu_head); ++ } ++ + __sta_info_free(local, sta); + + return 0; diff --git a/package/mac80211/patches/406-regd_no_assoc_hints.patch b/package/mac80211/patches/406-regd_no_assoc_hints.patch index 19336830fe..8ed03c6430 100644 --- a/package/mac80211/patches/406-regd_no_assoc_hints.patch +++ b/package/mac80211/patches/406-regd_no_assoc_hints.patch @@ -1,6 +1,6 @@ --- a/net/wireless/reg.c +++ b/net/wireless/reg.c -@@ -1656,6 +1656,8 @@ void regulatory_hint_11d(struct wiphy *w +@@ -1672,6 +1672,8 @@ void regulatory_hint_11d(struct wiphy *w enum environment_cap env = ENVIRON_ANY; struct regulatory_request *request; @@ -9,7 +9,7 @@ mutex_lock(®_mutex); if (unlikely(!last_request)) -@@ -1862,6 +1864,8 @@ static void restore_regulatory_settings( +@@ -1878,6 +1880,8 @@ 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 0dbb950319..09522cda6e 100644 --- a/package/mac80211/patches/410-ath9k_allow_adhoc_and_ap.patch +++ b/package/mac80211/patches/410-ath9k_allow_adhoc_and_ap.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c -@@ -1448,15 +1448,6 @@ static int ath9k_add_interface(struct ie +@@ -1458,15 +1458,6 @@ static int ath9k_add_interface(struct ie } } @@ -16,7 +16,7 @@ ath_dbg(common, ATH_DBG_CONFIG, "Attach a VIF of type: %d\n", vif->type); -@@ -1482,15 +1473,6 @@ static int ath9k_change_interface(struct +@@ -1492,15 +1483,6 @@ static int ath9k_change_interface(struct mutex_lock(&sc->mutex); ath9k_ps_wakeup(sc); 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 a964e70e52..29a79569c9 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 -@@ -1860,7 +1860,7 @@ ath5k_beacon_send(struct ath5k_hw *ah) +@@ -1867,7 +1867,7 @@ ath5k_beacon_send(struct ath5k_hw *ah) ah->bmisscount = 0; } @@ -27,7 +27,7 @@ ah->opmode == NL80211_IFTYPE_MESH_POINT) { u64 tsf = ath5k_hw_get_tsf64(ah); u32 tsftu = TSF_TO_TU(tsf); -@@ -1945,7 +1945,7 @@ ath5k_beacon_update_timers(struct ath5k_ +@@ -1952,7 +1952,7 @@ ath5k_beacon_update_timers(struct ath5k_ u64 hw_tsf; intval = ah->bintval & AR5K_BEACON_PERIOD; diff --git a/package/mac80211/patches/430-ath5k_disable_fast_cc.patch b/package/mac80211/patches/430-ath5k_disable_fast_cc.patch index 8ca821ced6..1948714313 100644 --- a/package/mac80211/patches/430-ath5k_disable_fast_cc.patch +++ b/package/mac80211/patches/430-ath5k_disable_fast_cc.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/ath/ath5k/reset.c +++ b/drivers/net/wireless/ath/ath5k/reset.c -@@ -1040,6 +1040,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, +@@ -1152,6 +1152,7 @@ ath5k_hw_reset(struct ath5k_hw *ah, enum tsf_lo = 0; mode = 0; @@ -8,7 +8,7 @@ /* * Sanity check for fast flag * Fast channel change only available -@@ -1047,6 +1048,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, +@@ -1159,6 +1160,7 @@ ath5k_hw_reset(struct ath5k_hw *ah, enum */ if (fast && (ah->ah_radio != AR5K_RF2413) && (ah->ah_radio != AR5K_RF5413)) diff --git a/package/mac80211/patches/510-ath9k_intr_mitigation_tweak.patch b/package/mac80211/patches/510-ath9k_intr_mitigation_tweak.patch index 72da8d8315..87e695b115 100644 --- a/package/mac80211/patches/510-ath9k_intr_mitigation_tweak.patch +++ b/package/mac80211/patches/510-ath9k_intr_mitigation_tweak.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c -@@ -1715,8 +1715,8 @@ int ath9k_hw_reset(struct ath_hw *ah, st +@@ -1795,8 +1795,8 @@ int ath9k_hw_reset(struct ath_hw *ah, st REG_WRITE(ah, AR_OBS, 8); if (ah->config.rx_intr_mitigation) { diff --git a/package/mac80211/patches/513-ath9k_channelbw_debugfs.patch b/package/mac80211/patches/513-ath9k_channelbw_debugfs.patch index ef568dc2ad..c5ca0e2b57 100644 --- a/package/mac80211/patches/513-ath9k_channelbw_debugfs.patch +++ b/package/mac80211/patches/513-ath9k_channelbw_debugfs.patch @@ -8,7 +8,7 @@ int chan_idx; int chan_is_ht; struct survey_info *cur_survey; -@@ -654,6 +655,7 @@ struct ath_softc { +@@ -655,6 +656,7 @@ struct ath_softc { u8 ant_tx, ant_rx; }; @@ -81,7 +81,7 @@ sc->debug.sampidx = 0; --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c -@@ -1554,7 +1554,7 @@ static void ath9k_disable_ps(struct ath_ +@@ -1564,7 +1564,7 @@ static void ath9k_disable_ps(struct ath_ } @@ -90,7 +90,7 @@ { struct ath_softc *sc = hw->priv; struct ath_hw *ah = sc->sc_ah; -@@ -1606,9 +1606,10 @@ static int ath9k_config(struct ieee80211 +@@ -1616,9 +1616,10 @@ static int ath9k_config(struct ieee80211 if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { struct ieee80211_channel *curchan = hw->conf.channel; @@ -102,7 +102,7 @@ unsigned long flags; if (ah->curchan) -@@ -1661,7 +1662,23 @@ static int ath9k_config(struct ieee80211 +@@ -1671,7 +1672,23 @@ static int ath9k_config(struct ieee80211 memset(&sc->survey[pos], 0, sizeof(struct survey_info)); } @@ -129,7 +129,7 @@ return -EINVAL; --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c -@@ -1549,6 +1549,10 @@ int ath9k_hw_reset(struct ath_hw *ah, st +@@ -1609,6 +1609,10 @@ int ath9k_hw_reset(struct ath_hw *ah, st caldata->rtt_hist.num_readings) allow_fbs = true; diff --git a/package/mac80211/patches/520-mac80211_ht_change_rate_update.patch b/package/mac80211/patches/520-mac80211_ht_change_rate_update.patch new file mode 100644 index 0000000000..3ffa31d66d --- /dev/null +++ b/package/mac80211/patches/520-mac80211_ht_change_rate_update.patch @@ -0,0 +1,35 @@ +--- a/net/mac80211/main.c ++++ b/net/mac80211/main.c +@@ -196,7 +196,9 @@ void ieee80211_bss_info_change_notify(st + u32 changed) + { + struct ieee80211_local *local = sdata->local; ++ struct ieee80211_supported_band *sband; + static const u8 zero[ETH_ALEN] = { 0 }; ++ struct sta_info *sta; + + if (!changed) + return; +@@ -226,6 +228,22 @@ void ieee80211_bss_info_change_notify(st + + switch (sdata->vif.type) { + case NL80211_IFTYPE_AP: ++ if (!(changed & BSS_CHANGED_HT)) ++ break; ++ ++ sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; ++ rcu_read_lock(); ++ list_for_each_entry(sta, &local->sta_list, list) { ++ if (sta->sdata != sdata && ++ (!sdata->bss || sta->sdata->bss != sdata->bss)) ++ continue; ++ ++ rate_control_rate_update(local, sband, sta, ++ IEEE80211_RC_HT_CHANGED, ++ local->_oper_channel_type); ++ } ++ rcu_read_unlock(); ++ break; + case NL80211_IFTYPE_ADHOC: + case NL80211_IFTYPE_WDS: + case NL80211_IFTYPE_MESH_POINT: diff --git a/package/mac80211/patches/520-mac80211_minstrel_ht_aggr_delay.patch b/package/mac80211/patches/520-mac80211_minstrel_ht_aggr_delay.patch deleted file mode 100644 index 8f074f0217..0000000000 --- a/package/mac80211/patches/520-mac80211_minstrel_ht_aggr_delay.patch +++ /dev/null @@ -1,49 +0,0 @@ ---- a/net/mac80211/rc80211_minstrel_ht.c -+++ b/net/mac80211/rc80211_minstrel_ht.c -@@ -357,10 +357,12 @@ minstrel_downgrade_rate(struct minstrel_ - } - - static void --minstrel_aggr_check(struct minstrel_priv *mp, struct ieee80211_sta *pubsta, struct sk_buff *skb) -+minstrel_aggr_check(struct minstrel_priv *mp, struct minstrel_ht_sta *mi, -+ struct ieee80211_sta *pubsta, struct sk_buff *skb) - { - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; - struct sta_info *sta = container_of(pubsta, struct sta_info, sta); -+ unsigned long t1, t2; - u16 tid; - - if (unlikely(!ieee80211_is_data_qos(hdr->frame_control))) -@@ -376,6 +378,12 @@ minstrel_aggr_check(struct minstrel_priv - if (skb_get_queue_mapping(skb) == IEEE80211_AC_VO) - return; - -+ t1 = mi->last_aggr_start_time[tid]; -+ t2 = t1 + msecs_to_jiffies(5000); -+ if (unlikely(time_in_range(jiffies, t1, t2))) -+ return; -+ -+ mi->last_aggr_start_time[tid] = jiffies; - ieee80211_start_tx_ba_session(pubsta, tid, 5000); - } - -@@ -455,7 +463,7 @@ minstrel_ht_tx_status(void *priv, struct - if (time_after(jiffies, mi->stats_update + (mp->update_interval / 2 * HZ) / 1000)) { - minstrel_ht_update_stats(mp, mi); - if (!(info->flags & IEEE80211_TX_CTL_AMPDU)) -- minstrel_aggr_check(mp, sta, skb); -+ minstrel_aggr_check(mp, mi, sta, skb); - } - } - ---- a/net/mac80211/rc80211_minstrel_ht.h -+++ b/net/mac80211/rc80211_minstrel_ht.h -@@ -109,6 +109,8 @@ struct minstrel_ht_sta { - - /* MCS rate group info and statistics */ - struct minstrel_mcs_group_data groups[MINSTREL_MAX_STREAMS * MINSTREL_STREAM_GROUPS]; -+ -+ unsigned long last_aggr_start_time[IEEE80211_QOS_CTL_TID_MASK + 1]; - }; - - struct minstrel_ht_sta_priv { diff --git a/package/mac80211/patches/521-mac80211_ht_change_rate_update.patch b/package/mac80211/patches/521-mac80211_ht_change_rate_update.patch deleted file mode 100644 index 75087028a2..0000000000 --- a/package/mac80211/patches/521-mac80211_ht_change_rate_update.patch +++ /dev/null @@ -1,35 +0,0 @@ ---- a/net/mac80211/main.c -+++ b/net/mac80211/main.c -@@ -237,7 +237,9 @@ void ieee80211_bss_info_change_notify(st - u32 changed) - { - struct ieee80211_local *local = sdata->local; -+ struct ieee80211_supported_band *sband; - static const u8 zero[ETH_ALEN] = { 0 }; -+ struct sta_info *sta; - - if (!changed) - return; -@@ -267,6 +269,22 @@ void ieee80211_bss_info_change_notify(st - - switch (sdata->vif.type) { - case NL80211_IFTYPE_AP: -+ if (!(changed & BSS_CHANGED_HT)) -+ break; -+ -+ sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; -+ rcu_read_lock(); -+ list_for_each_entry(sta, &local->sta_list, list) { -+ if (sta->sdata != sdata && -+ (!sdata->bss || sta->sdata->bss != sdata->bss)) -+ continue; -+ -+ rate_control_rate_update(local, sband, sta, -+ IEEE80211_RC_HT_CHANGED, -+ local->_oper_channel_type); -+ } -+ rcu_read_unlock(); -+ break; - case NL80211_IFTYPE_ADHOC: - case NL80211_IFTYPE_WDS: - case NL80211_IFTYPE_MESH_POINT: diff --git a/package/mac80211/patches/522-mac80211_reduce_txqueuelen.patch b/package/mac80211/patches/522-mac80211_reduce_txqueuelen.patch index 51e649ee81..4e4dcb8d4e 100644 --- a/package/mac80211/patches/522-mac80211_reduce_txqueuelen.patch +++ b/package/mac80211/patches/522-mac80211_reduce_txqueuelen.patch @@ -1,6 +1,6 @@ --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c -@@ -699,6 +699,7 @@ static const struct net_device_ops ieee8 +@@ -686,6 +686,7 @@ static const struct net_device_ops ieee8 static void ieee80211_if_setup(struct net_device *dev) { ether_setup(dev); diff --git a/package/mac80211/patches/523-minstrel_ht_optimize.patch b/package/mac80211/patches/523-minstrel_ht_optimize.patch deleted file mode 100644 index 8e804cae8b..0000000000 --- a/package/mac80211/patches/523-minstrel_ht_optimize.patch +++ /dev/null @@ -1,167 +0,0 @@ ---- a/net/mac80211/rc80211_minstrel_ht.h -+++ b/net/mac80211/rc80211_minstrel_ht.h -@@ -70,6 +70,8 @@ struct minstrel_mcs_group_data { - }; - - struct minstrel_ht_sta { -+ struct ieee80211_tx_rate tx_rates[3]; -+ - /* ampdu length (average, per sampling interval) */ - unsigned int ampdu_len; - unsigned int ampdu_packets; ---- a/net/mac80211/rc80211_minstrel_ht.c -+++ b/net/mac80211/rc80211_minstrel_ht.c -@@ -87,6 +87,10 @@ const struct mcs_group minstrel_mcs_grou - - static u8 sample_table[SAMPLE_COLUMNS][MCS_GROUP_RATES]; - -+static void -+minstrel_ht_set_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi, -+ struct ieee80211_tx_rate *rate, int index, -+ bool sample, bool rtscts); - /* - * Perform EWMA (Exponentially Weighted Moving Average) calculation - */ -@@ -174,6 +178,17 @@ minstrel_ht_calc_tp(struct minstrel_priv - mr->cur_tp = MINSTREL_TRUNC((1000000 / usecs) * mr->probability); - } - -+static void -+minstrel_ht_update_rates(struct minstrel_priv *mp, struct minstrel_ht_sta *mi) -+{ -+ minstrel_ht_set_rate(mp, mi, &mi->tx_rates[0], mi->max_tp_rate, -+ false, false); -+ minstrel_ht_set_rate(mp, mi, &mi->tx_rates[1], mi->max_tp_rate2, -+ false, true); -+ minstrel_ht_set_rate(mp, mi, &mi->tx_rates[2], mi->max_prob_rate, -+ false, true); -+} -+ - /* - * Update rate statistics and select new primary rates - * -@@ -294,6 +309,7 @@ minstrel_ht_update_stats(struct minstrel - } - } - -+ minstrel_ht_update_rates(mp, mi); - mi->stats_update = jiffies; - } - -@@ -332,8 +348,8 @@ minstrel_next_sample_idx(struct minstrel - } - - static void --minstrel_downgrade_rate(struct minstrel_ht_sta *mi, unsigned int *idx, -- bool primary) -+minstrel_downgrade_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi, -+ unsigned int *idx, bool primary) - { - int group, orig_group; - -@@ -352,6 +368,7 @@ minstrel_downgrade_rate(struct minstrel_ - *idx = mi->groups[group].max_tp_rate; - else - *idx = mi->groups[group].max_tp_rate2; -+ minstrel_ht_update_rates(mp, mi); - break; - } - } -@@ -452,13 +469,13 @@ minstrel_ht_tx_status(void *priv, struct - if (rate->attempts > 30 && - MINSTREL_FRAC(rate->success, rate->attempts) < - MINSTREL_FRAC(20, 100)) -- minstrel_downgrade_rate(mi, &mi->max_tp_rate, true); -+ minstrel_downgrade_rate(mp, mi, &mi->max_tp_rate, true); - - rate2 = minstrel_get_ratestats(mi, mi->max_tp_rate2); - if (rate2->attempts > 30 && - MINSTREL_FRAC(rate2->success, rate2->attempts) < - MINSTREL_FRAC(20, 100)) -- minstrel_downgrade_rate(mi, &mi->max_tp_rate2, false); -+ minstrel_downgrade_rate(mp, mi, &mi->max_tp_rate2, false); - - if (time_after(jiffies, mi->stats_update + (mp->update_interval / 2 * HZ) / 1000)) { - minstrel_ht_update_stats(mp, mi); -@@ -523,7 +540,6 @@ minstrel_calc_retransmit(struct minstrel - static void - minstrel_ht_set_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi, - struct ieee80211_tx_rate *rate, int index, -- struct ieee80211_tx_rate_control *txrc, - bool sample, bool rtscts) - { - const struct mcs_group *group = &minstrel_mcs_groups[index / MCS_GROUP_RATES]; -@@ -611,6 +627,7 @@ minstrel_ht_get_rate(void *priv, struct - struct minstrel_priv *mp = priv; - int sample_idx; - bool sample = false; -+ int last = 0; - - if (rate_control_send_low(sta, priv_sta, txrc)) - return; -@@ -636,11 +653,10 @@ minstrel_ht_get_rate(void *priv, struct - if (sample_idx >= 0) { - sample = true; - minstrel_ht_set_rate(mp, mi, &ar[0], sample_idx, -- txrc, true, false); -+ true, false); - info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE; - } else { -- minstrel_ht_set_rate(mp, mi, &ar[0], mi->max_tp_rate, -- txrc, false, false); -+ ar[0] = mi->tx_rates[0]; - } - - if (mp->hw->max_rates >= 3) { -@@ -650,33 +666,27 @@ minstrel_ht_get_rate(void *priv, struct - * max_tp_rate -> max_tp_rate2 -> max_prob_rate by default. - */ - if (sample_idx >= 0) -- minstrel_ht_set_rate(mp, mi, &ar[1], mi->max_tp_rate, -- txrc, false, false); -+ ar[1] = mi->tx_rates[0]; - else -- minstrel_ht_set_rate(mp, mi, &ar[1], mi->max_tp_rate2, -- txrc, false, true); -- -- minstrel_ht_set_rate(mp, mi, &ar[2], mi->max_prob_rate, -- txrc, false, !sample); -+ ar[1] = mi->tx_rates[1]; - -- ar[3].count = 0; -- ar[3].idx = -1; -+ ar[2] = mi->tx_rates[2]; -+ last = 3; - } else if (mp->hw->max_rates == 2) { - /* - * Only 2 tx rates supported, use - * sample_rate -> max_prob_rate for sampling and - * max_tp_rate -> max_prob_rate by default. - */ -- minstrel_ht_set_rate(mp, mi, &ar[1], mi->max_prob_rate, -- txrc, false, !sample); -- -- ar[2].count = 0; -- ar[2].idx = -1; -+ ar[1] = mi->tx_rates[2]; -+ last = 2; - } else { - /* Not using MRR, only use the first rate */ -- ar[1].count = 0; -- ar[1].idx = -1; -+ last = 1; -+ - } -+ ar[last].count = 0; -+ ar[last].idx = -1; - - mi->total_packets++; - -@@ -768,6 +778,7 @@ minstrel_ht_update_caps(void *priv, stru - if (!n_supported) - goto use_legacy; - -+ minstrel_ht_update_rates(mp, mi); - return; - - use_legacy: diff --git a/package/mac80211/patches/530-mac80211_cur_txpower.patch b/package/mac80211/patches/530-mac80211_cur_txpower.patch index 0fa6a229fd..8ed9216a7d 100644 --- a/package/mac80211/patches/530-mac80211_cur_txpower.patch +++ b/package/mac80211/patches/530-mac80211_cur_txpower.patch @@ -11,7 +11,7 @@ u16 listen_interval; --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c -@@ -1677,7 +1677,7 @@ static int ieee80211_get_tx_power(struct +@@ -1696,7 +1696,7 @@ static int ieee80211_get_tx_power(struct { struct ieee80211_local *local = wiphy_priv(wiphy); @@ -22,7 +22,7 @@ } --- a/net/mac80211/main.c +++ b/net/mac80211/main.c -@@ -208,6 +208,7 @@ int ieee80211_hw_config(struct ieee80211 +@@ -167,6 +167,7 @@ int ieee80211_hw_config(struct ieee80211 if (local->hw.conf.power_level != power) { changed |= IEEE80211_CONF_CHANGE_POWER; diff --git a/package/mac80211/patches/531-ath9k_cur_txpower.patch b/package/mac80211/patches/531-ath9k_cur_txpower.patch index 760f4d754e..bedfef8fd8 100644 --- a/package/mac80211/patches/531-ath9k_cur_txpower.patch +++ b/package/mac80211/patches/531-ath9k_cur_txpower.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c -@@ -1684,6 +1684,8 @@ int ath9k_config(struct ieee80211_hw *hw +@@ -1694,6 +1694,8 @@ int ath9k_config(struct ieee80211_hw *hw return -EINVAL; } @@ -9,7 +9,7 @@ /* * The most recent snapshot of channel->noisefloor for the old * channel is only available after the hardware reset. Copy it to -@@ -1699,6 +1701,7 @@ int ath9k_config(struct ieee80211_hw *hw +@@ -1709,6 +1711,7 @@ int ath9k_config(struct ieee80211_hw *hw sc->config.txpowlimit = 2 * conf->power_level; ath9k_cmn_update_txpow(ah, sc->curtxpow, sc->config.txpowlimit, &sc->curtxpow); diff --git a/package/mac80211/patches/542-ath9k_ar9280_cold_reset.patch b/package/mac80211/patches/542-ath9k_ar9280_cold_reset.patch index fe7afdedc5..70889d69d6 100644 --- a/package/mac80211/patches/542-ath9k_ar9280_cold_reset.patch +++ b/package/mac80211/patches/542-ath9k_ar9280_cold_reset.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c -@@ -1382,10 +1382,16 @@ static bool ath9k_hw_set_reset_reg(struc +@@ -1394,10 +1394,16 @@ static bool ath9k_hw_set_reset_reg(struc static bool ath9k_hw_chip_reset(struct ath_hw *ah, struct ath9k_channel *chan) { diff --git a/package/mac80211/patches/543-ath9k_enable_ar9100_ani.patch b/package/mac80211/patches/543-ath9k_enable_ar9100_ani.patch deleted file mode 100644 index 80b8d2e5f6..0000000000 --- a/package/mac80211/patches/543-ath9k_enable_ar9100_ani.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/drivers/net/wireless/ath/ath9k/hw.c -+++ b/drivers/net/wireless/ath/ath9k/hw.c -@@ -513,7 +513,7 @@ static int ath9k_hw_post_init(struct ath - return ecode; - } - -- if (!AR_SREV_9100(ah) && !AR_SREV_9340(ah)) { -+ if (!AR_SREV_9340(ah)) { - ath9k_hw_ani_setup(ah); - ath9k_hw_ani_init(ah); - } diff --git a/package/mac80211/patches/543-ath9k_fix_half_quarter_rx_latency.patch b/package/mac80211/patches/543-ath9k_fix_half_quarter_rx_latency.patch new file mode 100644 index 0000000000..45246ea468 --- /dev/null +++ b/package/mac80211/patches/543-ath9k_fix_half_quarter_rx_latency.patch @@ -0,0 +1,32 @@ +--- a/drivers/net/wireless/ath/ath9k/hw.c ++++ b/drivers/net/wireless/ath/ath9k/hw.c +@@ -1006,16 +1006,26 @@ void ath9k_hw_init_global_settings(struc + + if (IS_CHAN_HALF_RATE(chan)) { + eifs = 175; +- rx_lat *= 2; ++ ++ if (!AR_SREV_9300_20_OR_LATER(ah)) ++ rx_lat = 10; ++ else ++ rx_lat *= 2; ++ + tx_lat *= 2; + if (IS_CHAN_A_FAST_CLOCK(ah, chan)) +- tx_lat += 11; ++ tx_lat += 11; + + slottime = 13; + sifstime = 32; + } else if (IS_CHAN_QUARTER_RATE(chan)) { + eifs = 340; +- rx_lat = (rx_lat * 4) - 1; ++ ++ if (!AR_SREV_9300_20_OR_LATER(ah)) ++ rx_lat = 20; ++ else ++ rx_lat = (rx_lat * 4) - 1; ++ + tx_lat *= 4; + if (IS_CHAN_A_FAST_CLOCK(ah, chan)) + tx_lat += 22; diff --git a/package/mac80211/patches/544-ath9k_fix_half_quarter_sifs.patch b/package/mac80211/patches/544-ath9k_fix_half_quarter_sifs.patch new file mode 100644 index 0000000000..6bde7659f2 --- /dev/null +++ b/package/mac80211/patches/544-ath9k_fix_half_quarter_sifs.patch @@ -0,0 +1,44 @@ +--- a/drivers/net/wireless/ath/ath9k/hw.c ++++ b/drivers/net/wireless/ath/ath9k/hw.c +@@ -1007,31 +1007,35 @@ void ath9k_hw_init_global_settings(struc + if (IS_CHAN_HALF_RATE(chan)) { + eifs = 175; + +- if (!AR_SREV_9300_20_OR_LATER(ah)) ++ if (!AR_SREV_9300_20_OR_LATER(ah)) { + rx_lat = 10; +- else ++ sifstime = 8; ++ } else { + rx_lat *= 2; ++ sifstime = 32; ++ } + + tx_lat *= 2; + if (IS_CHAN_A_FAST_CLOCK(ah, chan)) + tx_lat += 11; + + slottime = 13; +- sifstime = 32; + } else if (IS_CHAN_QUARTER_RATE(chan)) { + eifs = 340; + +- if (!AR_SREV_9300_20_OR_LATER(ah)) ++ if (!AR_SREV_9300_20_OR_LATER(ah)) { + rx_lat = 20; +- else ++ sifstime = 8; ++ } else { + rx_lat = (rx_lat * 4) - 1; ++ sifstime = 64; ++ } + + tx_lat *= 4; + if (IS_CHAN_A_FAST_CLOCK(ah, chan)) + tx_lat += 22; + + slottime = 21; +- sifstime = 64; + } else { + if (AR_SREV_9287(ah) && AR_SREV_9287_13_OR_LATER(ah)) { + eifs = AR_D_GBL_IFS_EIFS_ASYNC_FIFO; diff --git a/package/mac80211/patches/544-ath9k_fix_sleep_mode_reg.patch b/package/mac80211/patches/544-ath9k_fix_sleep_mode_reg.patch deleted file mode 100644 index 2231b444e6..0000000000 --- a/package/mac80211/patches/544-ath9k_fix_sleep_mode_reg.patch +++ /dev/null @@ -1,12 +0,0 @@ ---- a/drivers/net/wireless/ath/ath9k/hw.c -+++ b/drivers/net/wireless/ath/ath9k/hw.c -@@ -1846,7 +1846,8 @@ static void ath9k_set_power_sleep(struct - } - - /* Clear Bit 14 of AR_WA after putting chip into Full Sleep mode. */ -- REG_WRITE(ah, AR_WA, ah->WARegVal & ~AR_WA_D3_L1_DISABLE); -+ if (AR_SREV_9300_20_OR_LATER(ah)) -+ REG_WRITE(ah, AR_WA, ah->WARegVal & ~AR_WA_D3_L1_DISABLE); - } - - /* diff --git a/package/mac80211/patches/551-ath9k_per_chain_signal_strength.patch b/package/mac80211/patches/551-ath9k_per_chain_signal_strength.patch index 378fb090b0..4040f865bb 100644 --- a/package/mac80211/patches/551-ath9k_per_chain_signal_strength.patch +++ b/package/mac80211/patches/551-ath9k_per_chain_signal_strength.patch @@ -139,7 +139,7 @@ u8 rs_num_delims; --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c -@@ -981,6 +981,7 @@ static int ath9k_rx_skb_preprocess(struc +@@ -980,6 +980,7 @@ static int ath9k_rx_skb_preprocess(struc bool *decrypt_error) { struct ath_hw *ah = common->ah; @@ -147,7 +147,7 @@ memset(rx_status, 0, sizeof(struct ieee80211_rx_status)); -@@ -1006,6 +1007,20 @@ static int ath9k_rx_skb_preprocess(struc +@@ -1005,6 +1006,20 @@ static int ath9k_rx_skb_preprocess(struc rx_status->antenna = rx_stats->rs_antenna; rx_status->flag |= RX_FLAG_MACTIME_MPDU; @@ -168,7 +168,7 @@ return 0; } -@@ -1536,14 +1551,14 @@ static void ath_ant_comb_scan(struct ath +@@ -1535,14 +1550,14 @@ static void ath_ant_comb_scan(struct ath struct ath_ant_comb *antcomb = &sc->ant_comb; int alt_ratio = 0, alt_rssi_avg = 0, main_rssi_avg = 0, curr_alt_set; int curr_main_set; @@ -189,7 +189,7 @@ /* Record packet only when both main_rssi and alt_rssi is positive */ --- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c -@@ -452,12 +452,12 @@ int ath9k_hw_process_rxdesc_edma(struct +@@ -484,12 +484,12 @@ int ath9k_hw_process_rxdesc_edma(struct /* XXX: Keycache */ rxs->rs_rssi = MS(rxsp->status5, AR_RxRSSICombined); @@ -271,7 +271,7 @@ RX_SAMP_DBG(rate) = rs->rs_rate; --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h -@@ -1621,6 +1621,8 @@ enum nl80211_sta_bss_param { +@@ -1651,6 +1651,8 @@ enum nl80211_sta_bss_param { * containing info as possible, see &enum nl80211_sta_bss_param * @NL80211_STA_INFO_CONNECTED_TIME: time since the station is last connected * @NL80211_STA_INFO_STA_FLAGS: Contains a struct nl80211_sta_flag_update. @@ -280,7 +280,7 @@ * @__NL80211_STA_INFO_AFTER_LAST: internal * @NL80211_STA_INFO_MAX: highest possible station info attribute */ -@@ -1643,6 +1645,8 @@ enum nl80211_sta_info { +@@ -1673,6 +1675,8 @@ enum nl80211_sta_info { NL80211_STA_INFO_BSS_PARAM, NL80211_STA_INFO_CONNECTED_TIME, NL80211_STA_INFO_STA_FLAGS, @@ -291,7 +291,7 @@ __NL80211_STA_INFO_AFTER_LAST, --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c -@@ -2287,6 +2287,33 @@ nla_put_failure: +@@ -2322,6 +2322,33 @@ nla_put_failure: return false; } @@ -325,7 +325,7 @@ static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq, int flags, struct net_device *dev, const u8 *mac_addr, struct station_info *sinfo) -@@ -2333,6 +2360,18 @@ static int nl80211_send_station(struct s +@@ -2368,6 +2395,18 @@ static int nl80211_send_station(struct s if (sinfo->filled & STATION_INFO_SIGNAL_AVG) NLA_PUT_U8(msg, NL80211_STA_INFO_SIGNAL_AVG, sinfo->signal_avg); @@ -346,7 +346,7 @@ NL80211_STA_INFO_TX_BITRATE)) --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c -@@ -330,6 +330,7 @@ static void sta_set_sinfo(struct sta_inf +@@ -340,6 +340,7 @@ static void sta_set_sinfo(struct sta_inf { struct ieee80211_sub_if_data *sdata = sta->sdata; struct timespec uptime; @@ -354,7 +354,7 @@ sinfo->generation = sdata->local->sta_generation; -@@ -365,6 +366,17 @@ static void sta_set_sinfo(struct sta_inf +@@ -375,6 +376,17 @@ static void sta_set_sinfo(struct sta_inf sinfo->signal = (s8)sta->last_signal; sinfo->signal_avg = (s8) -ewma_read(&sta->avg_signal); } diff --git a/package/mac80211/patches/560-ath9k_rework_send_bar.patch b/package/mac80211/patches/560-ath9k_rework_send_bar.patch new file mode 100644 index 0000000000..9176713a5b --- /dev/null +++ b/package/mac80211/patches/560-ath9k_rework_send_bar.patch @@ -0,0 +1,240 @@ +--- a/drivers/net/wireless/ath/ath9k/ath9k.h ++++ b/drivers/net/wireless/ath/ath9k/ath9k.h +@@ -159,6 +159,9 @@ void ath_descdma_cleanup(struct ath_soft + /* return block-ack bitmap index given sequence and starting sequence */ + #define ATH_BA_INDEX(_st, _seq) (((_seq) - (_st)) & (IEEE80211_SEQ_MAX - 1)) + ++/* return the seqno for _start + _offset */ ++#define ATH_BA_INDEX2SEQ(_seq, _offset) (((_seq) + (_offset)) & (IEEE80211_SEQ_MAX - 1)) ++ + /* returns delimiter padding required given the packet length */ + #define ATH_AGGR_GET_NDELIM(_len) \ + (((_len) >= ATH_AGGR_MINPLEN) ? 0 : \ +@@ -253,9 +256,9 @@ struct ath_atx_tid { + struct ath_node { + #ifdef CONFIG_ATH9K_DEBUGFS + struct list_head list; /* for sc->nodes */ ++#endif + struct ieee80211_sta *sta; /* station struct we're part of */ + struct ieee80211_vif *vif; /* interface with which we're associated */ +-#endif + struct ath_atx_tid tid[WME_NUM_TID]; + struct ath_atx_ac ac[WME_NUM_AC]; + int ps_key; +@@ -277,7 +280,6 @@ struct ath_tx_control { + }; + + #define ATH_TX_ERROR 0x01 +-#define ATH_TX_BAR 0x02 + + /** + * @txq_map: Index is mac80211 queue number. This is +--- a/drivers/net/wireless/ath/ath9k/main.c ++++ b/drivers/net/wireless/ath/ath9k/main.c +@@ -644,9 +644,9 @@ static void ath_node_attach(struct ath_s + spin_lock(&sc->nodes_lock); + list_add(&an->list, &sc->nodes); + spin_unlock(&sc->nodes_lock); ++#endif + an->sta = sta; + an->vif = vif; +-#endif + if (sc->sc_flags & SC_OP_TXAGGR) { + ath_tx_node_init(sc, an); + an->maxampdu = 1 << (IEEE80211_HT_MAX_AMPDU_FACTOR + +--- a/drivers/net/wireless/ath/ath9k/xmit.c ++++ b/drivers/net/wireless/ath/ath9k/xmit.c +@@ -53,7 +53,7 @@ static void ath_tx_complete(struct ath_s + int tx_flags, struct ath_txq *txq); + static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, + struct ath_txq *txq, struct list_head *bf_q, +- struct ath_tx_status *ts, int txok, int sendbar); ++ struct ath_tx_status *ts, int txok); + static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq, + struct list_head *head, bool internal); + static void ath_tx_rc_status(struct ath_softc *sc, struct ath_buf *bf, +@@ -150,6 +150,12 @@ static struct ath_frame_info *get_frame_ + return (struct ath_frame_info *) &tx_info->rate_driver_data[0]; + } + ++static void ath_send_bar(struct ath_atx_tid *tid, u16 seqno) ++{ ++ ieee80211_send_bar(tid->an->vif, tid->an->sta->addr, tid->tidno, ++ seqno << IEEE80211_SEQ_SEQ_SHIFT); ++} ++ + static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid) + { + struct ath_txq *txq = tid->ac->txq; +@@ -158,6 +164,7 @@ static void ath_tx_flush_tid(struct ath_ + struct list_head bf_head; + struct ath_tx_status ts; + struct ath_frame_info *fi; ++ bool sendbar = false; + + INIT_LIST_HEAD(&bf_head); + +@@ -172,7 +179,8 @@ static void ath_tx_flush_tid(struct ath_ + if (bf && fi->retries) { + list_add_tail(&bf->list, &bf_head); + ath_tx_update_baw(sc, tid, bf->bf_state.seqno); +- ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0, 1); ++ ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0); ++ sendbar = true; + } else { + ath_tx_send_normal(sc, txq, NULL, skb); + } +@@ -185,6 +193,9 @@ static void ath_tx_flush_tid(struct ath_ + } + + spin_unlock_bh(&txq->axq_lock); ++ ++ if (sendbar) ++ ath_send_bar(tid, tid->seq_start); + } + + static void ath_tx_update_baw(struct ath_softc *sc, struct ath_atx_tid *tid, +@@ -255,7 +266,7 @@ static void ath_tid_drain(struct ath_sof + ath_tx_update_baw(sc, tid, bf->bf_state.seqno); + + spin_unlock(&txq->axq_lock); +- ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0, 0); ++ ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0); + spin_lock(&txq->axq_lock); + } + +@@ -381,7 +392,7 @@ static void ath_tx_complete_aggr(struct + struct ath_buf *bf_next, *bf_last = bf->bf_lastbf; + struct list_head bf_head; + struct sk_buff_head bf_pending; +- u16 seq_st = 0, acked_cnt = 0, txfail_cnt = 0; ++ u16 seq_st = 0, acked_cnt = 0, txfail_cnt = 0, seq_first; + u32 ba[WME_BA_BMP_SIZE >> 5]; + int isaggr, txfail, txpending, sendbar = 0, needreset = 0, nbad = 0; + bool rc_update = true; +@@ -391,6 +402,7 @@ static void ath_tx_complete_aggr(struct + u8 tidno; + bool flush = !!(ts->ts_status & ATH9K_TX_FLUSH); + int i, retries; ++ int bar_index = -1; + + skb = bf->bf_mpdu; + hdr = (struct ieee80211_hdr *)skb->data; +@@ -416,8 +428,7 @@ static void ath_tx_complete_aggr(struct + if (!bf->bf_stale || bf_next != NULL) + list_move_tail(&bf->list, &bf_head); + +- ath_tx_complete_buf(sc, bf, txq, &bf_head, ts, +- 0, 0); ++ ath_tx_complete_buf(sc, bf, txq, &bf_head, ts, 0); + + bf = bf_next; + } +@@ -427,6 +438,7 @@ static void ath_tx_complete_aggr(struct + an = (struct ath_node *)sta->drv_priv; + tidno = ieee80211_get_qos_ctl(hdr)[0] & IEEE80211_QOS_CTL_TID_MASK; + tid = ATH_AN_2_TID(an, tidno); ++ seq_first = tid->seq_start; + + /* + * The hardware occasionally sends a tx status for the wrong TID. +@@ -495,8 +507,9 @@ static void ath_tx_complete_aggr(struct + txpending = 1; + } else { + txfail = 1; +- sendbar = 1; + txfail_cnt++; ++ bar_index = max_t(int, bar_index, ++ ATH_BA_INDEX(seq_first, seqno)); + } + } + +@@ -525,7 +538,7 @@ static void ath_tx_complete_aggr(struct + } + + ath_tx_complete_buf(sc, bf, txq, &bf_head, ts, +- !txfail, sendbar); ++ !txfail); + } else { + /* retry the un-acked ones */ + if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)) { +@@ -545,8 +558,10 @@ static void ath_tx_complete_aggr(struct + + ath_tx_complete_buf(sc, bf, txq, + &bf_head, +- ts, 0, +- !flush); ++ ts, 0); ++ bar_index = max_t(int, bar_index, ++ ATH_BA_INDEX(seq_first, ++ seqno)); + break; + } + +@@ -564,6 +579,9 @@ static void ath_tx_complete_aggr(struct + bf = bf_next; + } + ++ if (bar_index >= 0) ++ ath_send_bar(tid, ATH_BA_INDEX2SEQ(seq_first, bar_index + 1)); ++ + /* prepend un-acked frames to the beginning of the pending frame queue */ + if (!skb_queue_empty(&bf_pending)) { + if (an->sleeping) +@@ -1452,7 +1470,7 @@ static void ath_drain_txq_list(struct at + ath_tx_complete_aggr(sc, txq, bf, &bf_head, &ts, 0, + retry_tx); + else +- ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0, 0); ++ ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0); + spin_lock_bh(&txq->axq_lock); + } + } +@@ -1967,9 +1985,6 @@ static void ath_tx_complete(struct ath_s + + ath_dbg(common, ATH_DBG_XMIT, "TX complete: skb: %p\n", skb); + +- if (tx_flags & ATH_TX_BAR) +- tx_info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK; +- + if (!(tx_flags & ATH_TX_ERROR)) + /* Frame was ACKed */ + tx_info->flags |= IEEE80211_TX_STAT_ACK; +@@ -2013,16 +2028,13 @@ static void ath_tx_complete(struct ath_s + + static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, + struct ath_txq *txq, struct list_head *bf_q, +- struct ath_tx_status *ts, int txok, int sendbar) ++ struct ath_tx_status *ts, int txok) + { + struct sk_buff *skb = bf->bf_mpdu; + struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); + unsigned long flags; + int tx_flags = 0; + +- if (sendbar) +- tx_flags = ATH_TX_BAR; +- + if (!txok) + tx_flags |= ATH_TX_ERROR; + +@@ -2129,7 +2141,7 @@ static void ath_tx_process_buffer(struct + + if (!bf_isampdu(bf)) { + ath_tx_rc_status(sc, bf, ts, 1, txok ? 0 : 1, txok); +- ath_tx_complete_buf(sc, bf, txq, bf_head, ts, txok, 0); ++ ath_tx_complete_buf(sc, bf, txq, bf_head, ts, txok); + } else + ath_tx_complete_aggr(sc, txq, bf, bf_head, ts, txok, true); + +--- a/drivers/net/wireless/ath/ath9k/debug.c ++++ b/drivers/net/wireless/ath/ath9k/debug.c +@@ -856,7 +856,7 @@ void ath_debug_stat_tx(struct ath_softc + sc->debug.stats.txstats[qnum].tx_bytes_all += bf->bf_mpdu->len; + + if (bf_isampdu(bf)) { +- if (flags & ATH_TX_BAR) ++ if (flags & ATH_TX_ERROR) + TX_STAT_INC(qnum, a_xretries); + else + TX_STAT_INC(qnum, a_completed); diff --git a/package/mac80211/patches/560-mac80211_fix_ap_vlan_aggr.patch b/package/mac80211/patches/560-mac80211_fix_ap_vlan_aggr.patch deleted file mode 100644 index 051f1a91d1..0000000000 --- a/package/mac80211/patches/560-mac80211_fix_ap_vlan_aggr.patch +++ /dev/null @@ -1,95 +0,0 @@ ---- a/net/mac80211/driver-ops.h -+++ b/net/mac80211/driver-ops.h -@@ -10,6 +10,16 @@ static inline void check_sdata_in_driver - WARN_ON(!(sdata->flags & IEEE80211_SDATA_IN_DRIVER)); - } - -+static inline struct ieee80211_sub_if_data * -+get_bss_sdata(struct ieee80211_sub_if_data *sdata) -+{ -+ if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) -+ sdata = container_of(sdata->bss, struct ieee80211_sub_if_data, -+ u.ap); -+ -+ return sdata; -+} -+ - static inline void drv_tx(struct ieee80211_local *local, struct sk_buff *skb) - { - local->ops->tx(&local->hw, skb); -@@ -427,6 +437,7 @@ static inline void drv_sta_notify(struct - enum sta_notify_cmd cmd, - struct ieee80211_sta *sta) - { -+ sdata = get_bss_sdata(sdata); - check_sdata_in_driver(sdata); - - trace_drv_sta_notify(local, sdata, cmd, sta); -@@ -443,6 +454,7 @@ static inline int drv_sta_add(struct iee - - might_sleep(); - -+ sdata = get_bss_sdata(sdata); - check_sdata_in_driver(sdata); - - trace_drv_sta_add(local, sdata, sta); -@@ -460,6 +472,7 @@ static inline void drv_sta_remove(struct - { - might_sleep(); - -+ sdata = get_bss_sdata(sdata); - check_sdata_in_driver(sdata); - - trace_drv_sta_remove(local, sdata, sta); -@@ -553,6 +566,7 @@ static inline int drv_ampdu_action(struc - - might_sleep(); - -+ sdata = get_bss_sdata(sdata); - check_sdata_in_driver(sdata); - - trace_drv_ampdu_action(local, sdata, action, sta, tid, ssn, buf_size); ---- a/net/mac80211/sta_info.c -+++ b/net/mac80211/sta_info.c -@@ -353,10 +353,6 @@ static int sta_info_finish_insert(struct - - if (!sta->dummy || dummy_reinsert) { - /* notify driver */ -- if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) -- sdata = container_of(sdata->bss, -- struct ieee80211_sub_if_data, -- u.ap); - err = drv_sta_add(local, sdata, &sta->sta); - if (err) { - if (!async) ---- a/net/mac80211/agg-tx.c -+++ b/net/mac80211/agg-tx.c -@@ -550,7 +550,7 @@ void ieee80211_start_tx_ba_cb(struct iee - } - - mutex_lock(&local->sta_mtx); -- sta = sta_info_get(sdata, ra); -+ sta = sta_info_get_bss(sdata, ra); - if (!sta) { - mutex_unlock(&local->sta_mtx); - #ifdef CONFIG_MAC80211_HT_DEBUG -@@ -679,7 +679,7 @@ void ieee80211_stop_tx_ba_cb(struct ieee - - mutex_lock(&local->sta_mtx); - -- sta = sta_info_get(sdata, ra); -+ sta = sta_info_get_bss(sdata, ra); - if (!sta) { - #ifdef CONFIG_MAC80211_HT_DEBUG - printk(KERN_DEBUG "Could not find station: %pM\n", ra); ---- a/net/mac80211/agg-rx.c -+++ b/net/mac80211/agg-rx.c -@@ -109,7 +109,7 @@ void ieee80211_stop_rx_ba_session(struct - int i; - - rcu_read_lock(); -- sta = sta_info_get(sdata, addr); -+ sta = sta_info_get_bss(sdata, addr); - if (!sta) { - rcu_read_unlock(); - return; diff --git a/package/mac80211/patches/561-ath9k_reduce_indentation.patch b/package/mac80211/patches/561-ath9k_reduce_indentation.patch new file mode 100644 index 0000000000..08ff157c68 --- /dev/null +++ b/package/mac80211/patches/561-ath9k_reduce_indentation.patch @@ -0,0 +1,159 @@ +--- a/drivers/net/wireless/ath/ath9k/xmit.c ++++ b/drivers/net/wireless/ath/ath9k/xmit.c +@@ -490,27 +490,25 @@ static void ath_tx_complete_aggr(struct + } else if (!isaggr && txok) { + /* transmit completion */ + acked_cnt++; ++ } else if ((tid->state & AGGR_CLEANUP) || !retry) { ++ /* ++ * cleanup in progress, just fail ++ * the un-acked sub-frames ++ */ ++ txfail = 1; ++ } else if (flush) { ++ txpending = 1; ++ } else if (fi->retries < ATH_MAX_SW_RETRIES) { ++ if (txok || !an->sleeping) ++ ath_tx_set_retry(sc, txq, bf->bf_mpdu, ++ retries); ++ ++ txpending = 1; + } else { +- if ((tid->state & AGGR_CLEANUP) || !retry) { +- /* +- * cleanup in progress, just fail +- * the un-acked sub-frames +- */ +- txfail = 1; +- } else if (flush) { +- txpending = 1; +- } else if (fi->retries < ATH_MAX_SW_RETRIES) { +- if (txok || !an->sleeping) +- ath_tx_set_retry(sc, txq, bf->bf_mpdu, +- retries); +- +- txpending = 1; +- } else { +- txfail = 1; +- txfail_cnt++; +- bar_index = max_t(int, bar_index, +- ATH_BA_INDEX(seq_first, seqno)); +- } ++ txfail = 1; ++ txfail_cnt++; ++ bar_index = max_t(int, bar_index, ++ ATH_BA_INDEX(seq_first, seqno)); + } + + /* +@@ -541,32 +539,29 @@ static void ath_tx_complete_aggr(struct + !txfail); + } else { + /* retry the un-acked ones */ +- if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)) { +- if (bf->bf_next == NULL && bf_last->bf_stale) { +- struct ath_buf *tbf; +- +- tbf = ath_clone_txbuf(sc, bf_last); +- /* +- * Update tx baw and complete the +- * frame with failed status if we +- * run out of tx buf. +- */ +- if (!tbf) { +- spin_lock_bh(&txq->axq_lock); +- ath_tx_update_baw(sc, tid, seqno); +- spin_unlock_bh(&txq->axq_lock); +- +- ath_tx_complete_buf(sc, bf, txq, +- &bf_head, +- ts, 0); +- bar_index = max_t(int, bar_index, +- ATH_BA_INDEX(seq_first, +- seqno)); +- break; +- } ++ if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) && ++ bf->bf_next == NULL && bf_last->bf_stale) { ++ struct ath_buf *tbf; + +- fi->bf = tbf; ++ tbf = ath_clone_txbuf(sc, bf_last); ++ /* ++ * Update tx baw and complete the ++ * frame with failed status if we ++ * run out of tx buf. ++ */ ++ if (!tbf) { ++ spin_lock_bh(&txq->axq_lock); ++ ath_tx_update_baw(sc, tid, seqno); ++ spin_unlock_bh(&txq->axq_lock); ++ ++ ath_tx_complete_buf(sc, bf, txq, ++ &bf_head, ts, 0); ++ bar_index = max_t(int, bar_index, ++ ATH_BA_INDEX(seq_first, seqno)); ++ break; + } ++ ++ fi->bf = tbf; + } + + /* +@@ -654,24 +649,26 @@ static u32 ath_lookup_rate(struct ath_so + max_4ms_framelen = ATH_AMPDU_LIMIT_MAX; + + for (i = 0; i < 4; i++) { +- if (rates[i].count) { +- int modeidx; +- if (!(rates[i].flags & IEEE80211_TX_RC_MCS)) { +- legacy = 1; +- break; +- } +- +- if (rates[i].flags & IEEE80211_TX_RC_40_MHZ_WIDTH) +- modeidx = MCS_HT40; +- else +- modeidx = MCS_HT20; ++ int modeidx; + +- if (rates[i].flags & IEEE80211_TX_RC_SHORT_GI) +- modeidx++; ++ if (!rates[i].count) ++ continue; + +- frmlen = ath_max_4ms_framelen[modeidx][rates[i].idx]; +- max_4ms_framelen = min(max_4ms_framelen, frmlen); ++ if (!(rates[i].flags & IEEE80211_TX_RC_MCS)) { ++ legacy = 1; ++ break; + } ++ ++ if (rates[i].flags & IEEE80211_TX_RC_40_MHZ_WIDTH) ++ modeidx = MCS_HT40; ++ else ++ modeidx = MCS_HT20; ++ ++ if (rates[i].flags & IEEE80211_TX_RC_SHORT_GI) ++ modeidx++; ++ ++ frmlen = ath_max_4ms_framelen[modeidx][rates[i].idx]; ++ max_4ms_framelen = min(max_4ms_framelen, frmlen); + } + + /* +@@ -1598,11 +1595,9 @@ void ath_txq_schedule(struct ath_softc * + break; + } + +- if (!list_empty(&ac->tid_q)) { +- if (!ac->sched) { +- ac->sched = true; +- list_add_tail(&ac->list, &txq->axq_acq); +- } ++ if (!list_empty(&ac->tid_q) && !ac->sched) { ++ ac->sched = true; ++ list_add_tail(&ac->list, &txq->axq_acq); + } + + if (ac == last_ac || diff --git a/package/mac80211/patches/562-ath9k_remove_seq_incr.patch b/package/mac80211/patches/562-ath9k_remove_seq_incr.patch new file mode 100644 index 0000000000..a89d0a50f7 --- /dev/null +++ b/package/mac80211/patches/562-ath9k_remove_seq_incr.patch @@ -0,0 +1,13 @@ +--- a/drivers/net/wireless/ath/ath9k/xmit.c ++++ b/drivers/net/wireless/ath/ath9k/xmit.c +@@ -1742,10 +1742,6 @@ static void ath_tx_send_normal(struct at + list_add_tail(&bf->list, &bf_head); + bf->bf_state.bf_type = 0; + +- /* update starting sequence number for subsequent ADDBA request */ +- if (tid) +- INCR(tid->seq_start, IEEE80211_SEQ_MAX); +- + bf->bf_lastbf = bf; + ath_tx_fill_desc(sc, bf, txq, fi->framelen); + ath_tx_txqaddbuf(sc, txq, &bf_head, false); diff --git a/package/mac80211/patches/563-ath9k_simplify_tx_locking.patch b/package/mac80211/patches/563-ath9k_simplify_tx_locking.patch new file mode 100644 index 0000000000..93aa33d0c7 --- /dev/null +++ b/package/mac80211/patches/563-ath9k_simplify_tx_locking.patch @@ -0,0 +1,214 @@ +--- a/drivers/net/wireless/ath/ath9k/xmit.c ++++ b/drivers/net/wireless/ath/ath9k/xmit.c +@@ -169,13 +169,11 @@ static void ath_tx_flush_tid(struct ath_ + INIT_LIST_HEAD(&bf_head); + + memset(&ts, 0, sizeof(ts)); +- spin_lock_bh(&txq->axq_lock); + + while ((skb = __skb_dequeue(&tid->buf_q))) { + fi = get_frame_info(skb); + bf = fi->bf; + +- spin_unlock_bh(&txq->axq_lock); + if (bf && fi->retries) { + list_add_tail(&bf->list, &bf_head); + ath_tx_update_baw(sc, tid, bf->bf_state.seqno); +@@ -184,7 +182,6 @@ static void ath_tx_flush_tid(struct ath_ + } else { + ath_tx_send_normal(sc, txq, NULL, skb); + } +- spin_lock_bh(&txq->axq_lock); + } + + if (tid->baw_head == tid->baw_tail) { +@@ -192,8 +189,6 @@ static void ath_tx_flush_tid(struct ath_ + tid->state &= ~AGGR_CLEANUP; + } + +- spin_unlock_bh(&txq->axq_lock); +- + if (sendbar) + ath_send_bar(tid, tid->seq_start); + } +@@ -254,9 +249,7 @@ static void ath_tid_drain(struct ath_sof + bf = fi->bf; + + if (!bf) { +- spin_unlock(&txq->axq_lock); + ath_tx_complete(sc, skb, ATH_TX_ERROR, txq); +- spin_lock(&txq->axq_lock); + continue; + } + +@@ -265,9 +258,7 @@ static void ath_tid_drain(struct ath_sof + if (fi->retries) + ath_tx_update_baw(sc, tid, bf->bf_state.seqno); + +- spin_unlock(&txq->axq_lock); + ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0); +- spin_lock(&txq->axq_lock); + } + + tid->seq_next = tid->seq_start; +@@ -525,9 +516,7 @@ static void ath_tx_complete_aggr(struct + * complete the acked-ones/xretried ones; update + * block-ack window + */ +- spin_lock_bh(&txq->axq_lock); + ath_tx_update_baw(sc, tid, seqno); +- spin_unlock_bh(&txq->axq_lock); + + if (rc_update && (acked_cnt == 1 || txfail_cnt == 1)) { + memcpy(tx_info->control.rates, rates, sizeof(rates)); +@@ -550,9 +539,7 @@ static void ath_tx_complete_aggr(struct + * run out of tx buf. + */ + if (!tbf) { +- spin_lock_bh(&txq->axq_lock); + ath_tx_update_baw(sc, tid, seqno); +- spin_unlock_bh(&txq->axq_lock); + + ath_tx_complete_buf(sc, bf, txq, + &bf_head, ts, 0); +@@ -582,7 +569,6 @@ static void ath_tx_complete_aggr(struct + if (an->sleeping) + ieee80211_sta_set_buffered(sta, tid->tidno, true); + +- spin_lock_bh(&txq->axq_lock); + skb_queue_splice(&bf_pending, &tid->buf_q); + if (!an->sleeping) { + ath_tx_queue_tid(txq, tid); +@@ -590,7 +576,6 @@ static void ath_tx_complete_aggr(struct + if (ts->ts_status & ATH9K_TXERR_FILT) + tid->ac->clear_ps_filter = true; + } +- spin_unlock_bh(&txq->axq_lock); + } + + if (tid->state & AGGR_CLEANUP) +@@ -1190,9 +1175,9 @@ void ath_tx_aggr_stop(struct ath_softc * + txtid->state |= AGGR_CLEANUP; + else + txtid->state &= ~AGGR_ADDBA_COMPLETE; +- spin_unlock_bh(&txq->axq_lock); + + ath_tx_flush_tid(sc, txtid); ++ spin_unlock_bh(&txq->axq_lock); + } + + void ath_tx_aggr_sleep(struct ieee80211_sta *sta, struct ath_softc *sc, +@@ -1434,8 +1419,6 @@ static bool bf_is_ampdu_not_probing(stru + + static void ath_drain_txq_list(struct ath_softc *sc, struct ath_txq *txq, + struct list_head *list, bool retry_tx) +- __releases(txq->axq_lock) +- __acquires(txq->axq_lock) + { + struct ath_buf *bf, *lastbf; + struct list_head bf_head; +@@ -1462,13 +1445,11 @@ static void ath_drain_txq_list(struct at + if (bf_is_ampdu_not_probing(bf)) + txq->axq_ampdu_depth--; + +- spin_unlock_bh(&txq->axq_lock); + if (bf_isampdu(bf)) + ath_tx_complete_aggr(sc, txq, bf, &bf_head, &ts, 0, + retry_tx); + else + ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0); +- spin_lock_bh(&txq->axq_lock); + } + } + +@@ -1847,8 +1828,6 @@ static void ath_tx_start_dma(struct ath_ + struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); + struct ath_buf *bf; + +- spin_lock_bh(&txctl->txq->axq_lock); +- + if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && tid) { + /* + * Try aggregation if it's a unicast data frame +@@ -1858,7 +1837,7 @@ static void ath_tx_start_dma(struct ath_ + } else { + bf = ath_tx_setup_buffer(sc, txctl->txq, tid, skb); + if (!bf) +- goto out; ++ return; + + bf->bf_state.bfs_paprd = txctl->paprd; + +@@ -1867,9 +1846,6 @@ static void ath_tx_start_dma(struct ath_ + + ath_tx_send_normal(sc, txctl->txq, tid, skb); + } +- +-out: +- spin_unlock_bh(&txctl->txq->axq_lock); + } + + /* Upon failure caller should free skb */ +@@ -1949,15 +1925,19 @@ int ath_tx_start(struct ieee80211_hw *hw + */ + + q = skb_get_queue_mapping(skb); ++ + spin_lock_bh(&txq->axq_lock); ++ + if (txq == sc->tx.txq_map[q] && + ++txq->pending_frames > ATH_MAX_QDEPTH && !txq->stopped) { + ieee80211_stop_queue(sc->hw, q); + txq->stopped = 1; + } +- spin_unlock_bh(&txq->axq_lock); + + ath_tx_start_dma(sc, skb, txctl, tid); ++ ++ spin_unlock_bh(&txq->axq_lock); ++ + return 0; + } + +@@ -2003,7 +1983,6 @@ static void ath_tx_complete(struct ath_s + + q = skb_get_queue_mapping(skb); + if (txq == sc->tx.txq_map[q]) { +- spin_lock_bh(&txq->axq_lock); + if (WARN_ON(--txq->pending_frames < 0)) + txq->pending_frames = 0; + +@@ -2011,7 +1990,6 @@ static void ath_tx_complete(struct ath_s + ieee80211_wake_queue(sc->hw, q); + txq->stopped = 0; + } +- spin_unlock_bh(&txq->axq_lock); + } + + ieee80211_tx_status(hw, skb); +@@ -2117,8 +2095,6 @@ static void ath_tx_rc_status(struct ath_ + static void ath_tx_process_buffer(struct ath_softc *sc, struct ath_txq *txq, + struct ath_tx_status *ts, struct ath_buf *bf, + struct list_head *bf_head) +- __releases(txq->axq_lock) +- __acquires(txq->axq_lock) + { + int txok; + +@@ -2128,16 +2104,12 @@ static void ath_tx_process_buffer(struct + if (bf_is_ampdu_not_probing(bf)) + txq->axq_ampdu_depth--; + +- spin_unlock_bh(&txq->axq_lock); +- + if (!bf_isampdu(bf)) { + ath_tx_rc_status(sc, bf, ts, 1, txok ? 0 : 1, txok); + ath_tx_complete_buf(sc, bf, txq, bf_head, ts, txok); + } else + ath_tx_complete_aggr(sc, txq, bf, bf_head, ts, txok, true); + +- spin_lock_bh(&txq->axq_lock); +- + if (sc->sc_flags & SC_OP_TXAGGR) + ath_txq_schedule(sc, txq); + } diff --git a/package/mac80211/patches/564-ath9k_track_last_bar.patch b/package/mac80211/patches/564-ath9k_track_last_bar.patch new file mode 100644 index 0000000000..34a4dd1ddb --- /dev/null +++ b/package/mac80211/patches/564-ath9k_track_last_bar.patch @@ -0,0 +1,82 @@ +--- a/drivers/net/wireless/ath/ath9k/ath9k.h ++++ b/drivers/net/wireless/ath/ath9k/ath9k.h +@@ -242,6 +242,7 @@ struct ath_atx_tid { + struct ath_atx_ac *ac; + unsigned long tx_buf[BITS_TO_LONGS(ATH_TID_MAX_BUFS)]; + int buf_pending; ++ int bar_index; + u16 seq_start; + u16 seq_next; + u16 baw_size; +--- a/drivers/net/wireless/ath/ath9k/xmit.c ++++ b/drivers/net/wireless/ath/ath9k/xmit.c +@@ -206,6 +206,8 @@ static void ath_tx_update_baw(struct ath + while (tid->baw_head != tid->baw_tail && !test_bit(tid->baw_head, tid->tx_buf)) { + INCR(tid->seq_start, IEEE80211_SEQ_MAX); + INCR(tid->baw_head, ATH_TID_MAX_BUFS); ++ if (tid->bar_index >= 0) ++ tid->bar_index--; + } + } + +@@ -263,6 +265,7 @@ static void ath_tid_drain(struct ath_sof + + tid->seq_next = tid->seq_start; + tid->baw_tail = tid->baw_head; ++ tid->bar_index = -1; + } + + static void ath_tx_set_retry(struct ath_softc *sc, struct ath_txq *txq, +@@ -561,8 +564,12 @@ static void ath_tx_complete_aggr(struct + bf = bf_next; + } + +- if (bar_index >= 0) ++ if (bar_index >= 0) { ++ u16 bar_seq = ATH_BA_INDEX2SEQ(seq_first, bar_index); + ath_send_bar(tid, ATH_BA_INDEX2SEQ(seq_first, bar_index + 1)); ++ if (BAW_WITHIN(tid->seq_start, tid->baw_size, bar_seq)) ++ tid->bar_index = ATH_BA_INDEX(tid->seq_start, bar_seq); ++ } + + /* prepend un-acked frames to the beginning of the pending frame queue */ + if (!skb_queue_empty(&bf_pending)) { +@@ -789,8 +796,6 @@ static enum ATH_AGGR_STATUS ath_tx_form_ + + bf->bf_state.bf_type = BUF_AMPDU | BUF_AGGR; + seqno = bf->bf_state.seqno; +- if (!bf_first) +- bf_first = bf; + + /* do not step over block-ack window */ + if (!BAW_WITHIN(tid->seq_start, tid->baw_size, seqno)) { +@@ -798,6 +803,21 @@ static enum ATH_AGGR_STATUS ath_tx_form_ + break; + } + ++ if (tid->bar_index > ATH_BA_INDEX(tid->seq_start, seqno)) { ++ struct ath_tx_status ts = {}; ++ struct list_head bf_head; ++ ++ INIT_LIST_HEAD(&bf_head); ++ list_add(&bf->list, &bf_head); ++ __skb_unlink(skb, &tid->buf_q); ++ ath_tx_update_baw(sc, tid, seqno); ++ ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0); ++ continue; ++ } ++ ++ if (!bf_first) ++ bf_first = bf; ++ + if (!rl) { + aggr_limit = ath_lookup_rate(sc, bf, tid); + rl = 1; +@@ -1141,6 +1161,7 @@ int ath_tx_aggr_start(struct ath_softc * + txtid->state |= AGGR_ADDBA_PROGRESS; + txtid->paused = true; + *ssn = txtid->seq_start = txtid->seq_next; ++ txtid->bar_index = -1; + + memset(txtid->tx_buf, 0, sizeof(txtid->tx_buf)); + txtid->baw_head = txtid->baw_tail = 0; diff --git a/package/mac80211/patches/565-ath9k_fix_lockup.patch b/package/mac80211/patches/565-ath9k_fix_lockup.patch new file mode 100644 index 0000000000..6bc9171c3e --- /dev/null +++ b/package/mac80211/patches/565-ath9k_fix_lockup.patch @@ -0,0 +1,299 @@ +--- a/drivers/net/wireless/ath/ath9k/xmit.c ++++ b/drivers/net/wireless/ath/ath9k/xmit.c +@@ -104,6 +104,29 @@ static int ath_max_4ms_framelen[4][32] = + /* Aggregation logic */ + /*********************/ + ++static void ath_txq_lock(struct ath_softc *sc, struct ath_txq *txq) ++{ ++ spin_lock_bh(&txq->axq_lock); ++} ++ ++static void ath_txq_unlock(struct ath_softc *sc, struct ath_txq *txq) ++{ ++ spin_unlock_bh(&txq->axq_lock); ++} ++ ++static void ath_txq_unlock_complete(struct ath_softc *sc, struct ath_txq *txq) ++{ ++ struct sk_buff_head q; ++ struct sk_buff *skb; ++ ++ __skb_queue_head_init(&q); ++ skb_queue_splice_init(&txq->complete_q, &q); ++ spin_unlock_bh(&txq->axq_lock); ++ ++ while ((skb = __skb_dequeue(&q))) ++ ieee80211_tx_status(sc->hw, skb); ++} ++ + static void ath_tx_queue_tid(struct ath_txq *txq, struct ath_atx_tid *tid) + { + struct ath_atx_ac *ac = tid->ac; +@@ -130,7 +153,7 @@ static void ath_tx_resume_tid(struct ath + + WARN_ON(!tid->paused); + +- spin_lock_bh(&txq->axq_lock); ++ ath_txq_lock(sc, txq); + tid->paused = false; + + if (skb_queue_empty(&tid->buf_q)) +@@ -139,7 +162,7 @@ static void ath_tx_resume_tid(struct ath + ath_tx_queue_tid(txq, tid); + ath_txq_schedule(sc, txq); + unlock: +- spin_unlock_bh(&txq->axq_lock); ++ ath_txq_unlock_complete(sc, txq); + } + + static struct ath_frame_info *get_frame_info(struct sk_buff *skb) +@@ -189,8 +212,11 @@ static void ath_tx_flush_tid(struct ath_ + tid->state &= ~AGGR_CLEANUP; + } + +- if (sendbar) ++ if (sendbar) { ++ ath_txq_unlock(sc, txq); + ath_send_bar(tid, tid->seq_start); ++ ath_txq_lock(sc, txq); ++ } + } + + static void ath_tx_update_baw(struct ath_softc *sc, struct ath_atx_tid *tid, +@@ -564,13 +590,6 @@ static void ath_tx_complete_aggr(struct + bf = bf_next; + } + +- if (bar_index >= 0) { +- u16 bar_seq = ATH_BA_INDEX2SEQ(seq_first, bar_index); +- ath_send_bar(tid, ATH_BA_INDEX2SEQ(seq_first, bar_index + 1)); +- if (BAW_WITHIN(tid->seq_start, tid->baw_size, bar_seq)) +- tid->bar_index = ATH_BA_INDEX(tid->seq_start, bar_seq); +- } +- + /* prepend un-acked frames to the beginning of the pending frame queue */ + if (!skb_queue_empty(&bf_pending)) { + if (an->sleeping) +@@ -585,6 +604,17 @@ static void ath_tx_complete_aggr(struct + } + } + ++ if (bar_index >= 0) { ++ u16 bar_seq = ATH_BA_INDEX2SEQ(seq_first, bar_index); ++ ++ if (BAW_WITHIN(tid->seq_start, tid->baw_size, bar_seq)) ++ tid->bar_index = ATH_BA_INDEX(tid->seq_start, bar_seq); ++ ++ ath_txq_unlock(sc, txq); ++ ath_send_bar(tid, ATH_BA_INDEX2SEQ(seq_first, bar_index + 1)); ++ ath_txq_lock(sc, txq); ++ } ++ + if (tid->state & AGGR_CLEANUP) + ath_tx_flush_tid(sc, tid); + +@@ -1183,7 +1213,7 @@ void ath_tx_aggr_stop(struct ath_softc * + return; + } + +- spin_lock_bh(&txq->axq_lock); ++ ath_txq_lock(sc, txq); + txtid->paused = true; + + /* +@@ -1198,7 +1228,7 @@ void ath_tx_aggr_stop(struct ath_softc * + txtid->state &= ~AGGR_ADDBA_COMPLETE; + + ath_tx_flush_tid(sc, txtid); +- spin_unlock_bh(&txq->axq_lock); ++ ath_txq_unlock_complete(sc, txq); + } + + void ath_tx_aggr_sleep(struct ieee80211_sta *sta, struct ath_softc *sc, +@@ -1219,7 +1249,7 @@ void ath_tx_aggr_sleep(struct ieee80211_ + ac = tid->ac; + txq = ac->txq; + +- spin_lock_bh(&txq->axq_lock); ++ ath_txq_lock(sc, txq); + + buffered = !skb_queue_empty(&tid->buf_q); + +@@ -1231,7 +1261,7 @@ void ath_tx_aggr_sleep(struct ieee80211_ + list_del(&ac->list); + } + +- spin_unlock_bh(&txq->axq_lock); ++ ath_txq_unlock(sc, txq); + + ieee80211_sta_set_buffered(sta, tidno, buffered); + } +@@ -1250,7 +1280,7 @@ void ath_tx_aggr_wakeup(struct ath_softc + ac = tid->ac; + txq = ac->txq; + +- spin_lock_bh(&txq->axq_lock); ++ ath_txq_lock(sc, txq); + ac->clear_ps_filter = true; + + if (!skb_queue_empty(&tid->buf_q) && !tid->paused) { +@@ -1258,7 +1288,7 @@ void ath_tx_aggr_wakeup(struct ath_softc + ath_txq_schedule(sc, txq); + } + +- spin_unlock_bh(&txq->axq_lock); ++ ath_txq_unlock_complete(sc, txq); + } + } + +@@ -1358,6 +1388,7 @@ struct ath_txq *ath_txq_setup(struct ath + txq->axq_qnum = axq_qnum; + txq->mac80211_qnum = -1; + txq->axq_link = NULL; ++ __skb_queue_head_init(&txq->complete_q); + INIT_LIST_HEAD(&txq->axq_q); + INIT_LIST_HEAD(&txq->axq_acq); + spin_lock_init(&txq->axq_lock); +@@ -1482,7 +1513,8 @@ static void ath_drain_txq_list(struct at + */ + void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx) + { +- spin_lock_bh(&txq->axq_lock); ++ ath_txq_lock(sc, txq); ++ + if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) { + int idx = txq->txq_tailidx; + +@@ -1503,7 +1535,7 @@ void ath_draintxq(struct ath_softc *sc, + if ((sc->sc_flags & SC_OP_TXAGGR) && !retry_tx) + ath_txq_drain_pending_buffers(sc, txq); + +- spin_unlock_bh(&txq->axq_lock); ++ ath_txq_unlock_complete(sc, txq); + } + + bool ath_drain_all_txq(struct ath_softc *sc, bool retry_tx) +@@ -1947,7 +1979,7 @@ int ath_tx_start(struct ieee80211_hw *hw + + q = skb_get_queue_mapping(skb); + +- spin_lock_bh(&txq->axq_lock); ++ ath_txq_lock(sc, txq); + + if (txq == sc->tx.txq_map[q] && + ++txq->pending_frames > ATH_MAX_QDEPTH && !txq->stopped) { +@@ -1957,7 +1989,7 @@ int ath_tx_start(struct ieee80211_hw *hw + + ath_tx_start_dma(sc, skb, txctl, tid); + +- spin_unlock_bh(&txq->axq_lock); ++ ath_txq_unlock(sc, txq); + + return 0; + } +@@ -1969,7 +2001,6 @@ int ath_tx_start(struct ieee80211_hw *hw + static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, + int tx_flags, struct ath_txq *txq) + { +- struct ieee80211_hw *hw = sc->hw; + struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); + struct ath_common *common = ath9k_hw_common(sc->sc_ah); + struct ieee80211_hdr * hdr = (struct ieee80211_hdr *)skb->data; +@@ -2013,7 +2044,7 @@ static void ath_tx_complete(struct ath_s + } + } + +- ieee80211_tx_status(hw, skb); ++ __skb_queue_tail(&txq->complete_q, skb); + } + + static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, +@@ -2149,7 +2180,7 @@ static void ath_tx_processq(struct ath_s + txq->axq_qnum, ath9k_hw_gettxbuf(sc->sc_ah, txq->axq_qnum), + txq->axq_link); + +- spin_lock_bh(&txq->axq_lock); ++ ath_txq_lock(sc, txq); + for (;;) { + if (work_pending(&sc->hw_reset_work)) + break; +@@ -2208,7 +2239,7 @@ static void ath_tx_processq(struct ath_s + + ath_tx_process_buffer(sc, txq, &ts, bf, &bf_head); + } +- spin_unlock_bh(&txq->axq_lock); ++ ath_txq_unlock_complete(sc, txq); + } + + static void ath_tx_complete_poll_work(struct work_struct *work) +@@ -2225,17 +2256,17 @@ static void ath_tx_complete_poll_work(st + for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) + if (ATH_TXQ_SETUP(sc, i)) { + txq = &sc->tx.txq[i]; +- spin_lock_bh(&txq->axq_lock); ++ ath_txq_lock(sc, txq); + if (txq->axq_depth) { + if (txq->axq_tx_inprogress) { + needreset = true; +- spin_unlock_bh(&txq->axq_lock); ++ ath_txq_unlock(sc, txq); + break; + } else { + txq->axq_tx_inprogress = true; + } + } +- spin_unlock_bh(&txq->axq_lock); ++ ath_txq_unlock_complete(sc, txq); + } + + if (needreset) { +@@ -2293,10 +2324,10 @@ void ath_tx_edma_tasklet(struct ath_soft + + txq = &sc->tx.txq[ts.qid]; + +- spin_lock_bh(&txq->axq_lock); ++ ath_txq_lock(sc, txq); + + if (list_empty(&txq->txq_fifo[txq->txq_tailidx])) { +- spin_unlock_bh(&txq->axq_lock); ++ ath_txq_unlock(sc, txq); + return; + } + +@@ -2322,7 +2353,7 @@ void ath_tx_edma_tasklet(struct ath_soft + } + + ath_tx_process_buffer(sc, txq, &ts, bf, &bf_head); +- spin_unlock_bh(&txq->axq_lock); ++ ath_txq_unlock_complete(sc, txq); + } + } + +@@ -2460,7 +2491,7 @@ void ath_tx_node_cleanup(struct ath_soft + ac = tid->ac; + txq = ac->txq; + +- spin_lock_bh(&txq->axq_lock); ++ ath_txq_lock(sc, txq); + + if (tid->sched) { + list_del(&tid->list); +@@ -2476,6 +2507,6 @@ void ath_tx_node_cleanup(struct ath_soft + tid->state &= ~AGGR_ADDBA_COMPLETE; + tid->state &= ~AGGR_CLEANUP; + +- spin_unlock_bh(&txq->axq_lock); ++ ath_txq_unlock(sc, txq); + } + } +--- a/drivers/net/wireless/ath/ath9k/ath9k.h ++++ b/drivers/net/wireless/ath/ath9k/ath9k.h +@@ -196,6 +196,7 @@ struct ath_txq { + u8 txq_headidx; + u8 txq_tailidx; + int pending_frames; ++ struct sk_buff_head complete_q; + }; + + struct ath_atx_ac { diff --git a/package/mac80211/patches/570-ath9k_mci_static.patch b/package/mac80211/patches/570-ath9k_mci_static.patch new file mode 100644 index 0000000000..9a337c0d60 --- /dev/null +++ b/package/mac80211/patches/570-ath9k_mci_static.patch @@ -0,0 +1,37 @@ +--- a/drivers/net/wireless/ath/ath9k/mci.c ++++ b/drivers/net/wireless/ath/ath9k/mci.c +@@ -234,8 +234,8 @@ static void ath_mci_cal_msg(struct ath_s + } + } + +-void ath_mci_process_profile(struct ath_softc *sc, +- struct ath_mci_profile_info *info) ++static void ath_mci_process_profile(struct ath_softc *sc, ++ struct ath_mci_profile_info *info) + { + struct ath_common *common = ath9k_hw_common(sc->sc_ah); + struct ath_btcoex *btcoex = &sc->btcoex; +@@ -261,8 +261,8 @@ void ath_mci_process_profile(struct ath_ + ath_mci_update_scheme(sc); + } + +-void ath_mci_process_status(struct ath_softc *sc, +- struct ath_mci_profile_status *status) ++static void ath_mci_process_status(struct ath_softc *sc, ++ struct ath_mci_profile_status *status) + { + struct ath_common *common = ath9k_hw_common(sc->sc_ah); + struct ath_btcoex *btcoex = &sc->btcoex; +--- a/drivers/net/wireless/ath/ath9k/mci.h ++++ b/drivers/net/wireless/ath/ath9k/mci.h +@@ -128,10 +128,6 @@ struct ath_mci_coex { + }; + + void ath_mci_flush_profile(struct ath_mci_profile *mci); +-void ath_mci_process_profile(struct ath_softc *sc, +- struct ath_mci_profile_info *info); +-void ath_mci_process_status(struct ath_softc *sc, +- struct ath_mci_profile_status *status); + int ath_mci_setup(struct ath_softc *sc); + void ath_mci_cleanup(struct ath_softc *sc); + void ath_mci_intr(struct ath_softc *sc); diff --git a/package/mac80211/patches/571-ath9k_btcoex_optional.patch b/package/mac80211/patches/571-ath9k_btcoex_optional.patch new file mode 100644 index 0000000000..c73ad1a4f3 --- /dev/null +++ b/package/mac80211/patches/571-ath9k_btcoex_optional.patch @@ -0,0 +1,544 @@ +--- a/drivers/net/wireless/ath/ath9k/Kconfig ++++ b/drivers/net/wireless/ath/ath9k/Kconfig +@@ -59,6 +59,14 @@ config ATH9K_RATE_CONTROL + Say Y, if you want to use the ath9k specific rate control + module instead of minstrel_ht. + ++config ATH9K_BTCOEX_SUPPORT ++ bool "Atheros ath9k bluetooth coexistence support" ++ depends on ATH9K ++ default y ++ ---help--- ++ Say Y, if you want to use the ath9k radios together with ++ Bluetooth modules in the same system. ++ + config ATH9K_HTC + tristate "Atheros HTC based wireless cards support" + depends on USB && MAC80211 +--- a/drivers/net/wireless/ath/ath9k/hw.h ++++ b/drivers/net/wireless/ath/ath9k/hw.h +@@ -210,7 +210,11 @@ enum ath9k_hw_caps { + ATH9K_HW_CAP_5GHZ = BIT(14), + ATH9K_HW_CAP_APM = BIT(15), + ATH9K_HW_CAP_RTT = BIT(16), ++#ifdef CONFIG_ATH9K_BTCOEX_SUPPORT + ATH9K_HW_CAP_MCI = BIT(17), ++#else ++ ATH9K_HW_CAP_MCI = 0, ++#endif + }; + + struct ath9k_hw_capabilities { +@@ -1229,6 +1233,16 @@ void ar9003_mci_sync_bt_state(struct ath + void ar9003_mci_get_interrupt(struct ath_hw *ah, u32 *raw_intr, + u32 *rx_msg_intr); + ++#ifdef CONFIG_ATH9K_BTCOEX_SUPPORT ++static inline enum ath_btcoex_scheme ++ath9k_hw_get_btcoex_scheme(struct ath_hw *ah) ++{ ++ return ah->btcoex_hw.scheme; ++} ++#else ++#define ath9k_hw_get_btcoex_scheme(...) ATH_BTCOEX_CFG_NONE ++#endif ++ + #define ATH9K_CLOCK_RATE_CCK 22 + #define ATH9K_CLOCK_RATE_5GHZ_OFDM 40 + #define ATH9K_CLOCK_RATE_2GHZ_OFDM 44 +--- a/drivers/net/wireless/ath/ath9k/init.c ++++ b/drivers/net/wireless/ath/ath9k/init.c +@@ -411,7 +411,7 @@ static int ath9k_init_btcoex(struct ath_ + struct ath_hw *ah = sc->sc_ah; + int r; + +- switch (sc->sc_ah->btcoex_hw.scheme) { ++ switch (ath9k_hw_get_btcoex_scheme(sc->sc_ah)) { + case ATH_BTCOEX_CFG_NONE: + break; + case ATH_BTCOEX_CFG_2WIRE: +@@ -866,10 +866,10 @@ static void ath9k_deinit_softc(struct at + kfree(sc->sbands[IEEE80211_BAND_5GHZ].channels); + + if ((sc->btcoex.no_stomp_timer) && +- sc->sc_ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE) ++ ath9k_hw_get_btcoex_scheme(sc->sc_ah) == ATH_BTCOEX_CFG_3WIRE) + ath_gen_timer_free(sc->sc_ah, sc->btcoex.no_stomp_timer); + +- if (sc->sc_ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_MCI) ++ if (ath9k_hw_get_btcoex_scheme(sc->sc_ah) == ATH_BTCOEX_CFG_MCI) + ath_mci_cleanup(sc); + + for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) +--- a/drivers/net/wireless/ath/ath9k/pci.c ++++ b/drivers/net/wireless/ath/ath9k/pci.c +@@ -121,7 +121,7 @@ static void ath_pci_aspm_init(struct ath + if (!parent) + return; + +- if (ah->btcoex_hw.scheme != ATH_BTCOEX_CFG_NONE) { ++ if (ath9k_hw_get_btcoex_scheme(ah) != ATH_BTCOEX_CFG_NONE) { + /* Bluetooth coexistance requires disabling ASPM. */ + pci_read_config_byte(pdev, pos + PCI_EXP_LNKCTL, &aspm); + aspm &= ~(PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1); +--- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c ++++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c +@@ -610,7 +610,7 @@ static void ath9k_init_btcoex(struct ath + { + int qnum; + +- switch (priv->ah->btcoex_hw.scheme) { ++ switch (ath9k_hw_get_btcoex_scheme(priv->ah)) { + case ATH_BTCOEX_CFG_NONE: + break; + case ATH_BTCOEX_CFG_3WIRE: +@@ -704,7 +704,8 @@ static int ath9k_init_priv(struct ath9k_ + + if (product && strncmp(product, ATH_HTC_BTCOEX_PRODUCT_ID, 5) == 0) { + ah->btcoex_hw.scheme = ATH_BTCOEX_CFG_3WIRE; +- ath9k_init_btcoex(priv); ++ if (ath9k_hw_get_btcoex_scheme(ah) != ATH_BTCOEX_CFG_NONE) ++ ath9k_init_btcoex(priv); + } + + return 0; +--- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c ++++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c +@@ -958,7 +958,7 @@ static int ath9k_htc_start(struct ieee80 + mod_timer(&priv->tx.cleanup_timer, + jiffies + msecs_to_jiffies(ATH9K_HTC_TX_CLEANUP_INTERVAL)); + +- if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE) { ++ if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_3WIRE) { + ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT, + AR_STOMP_LOW_WLAN_WGHT); + ath9k_hw_btcoex_enable(ah); +@@ -1010,7 +1010,8 @@ static void ath9k_htc_stop(struct ieee80 + + mutex_lock(&priv->mutex); + +- if (ah->btcoex_hw.enabled) { ++ if (ah->btcoex_hw.enabled && ++ ath9k_hw_get_btcoex_scheme(ah) != ATH_BTCOEX_CFG_NONE) { + ath9k_hw_btcoex_disable(ah); + if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE) + ath_htc_cancel_btcoex_work(priv); +--- a/drivers/net/wireless/ath/ath9k/main.c ++++ b/drivers/net/wireless/ath/ath9k/main.c +@@ -742,11 +742,11 @@ void ath9k_tasklet(unsigned long data) + ath_tx_tasklet(sc); + } + +- if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE) ++ if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_3WIRE) + if (status & ATH9K_INT_GENTIMER) + ath_gen_timer_isr(sc->sc_ah); + +- if (status & ATH9K_INT_MCI) ++ if ((status & ATH9K_INT_MCI) && ATH9K_HW_CAP_MCI) + ath_mci_intr(sc); + + out: +@@ -1083,14 +1083,14 @@ static int ath9k_start(struct ieee80211_ + + spin_unlock_bh(&sc->sc_pcu_lock); + +- if ((ah->btcoex_hw.scheme != ATH_BTCOEX_CFG_NONE) && ++ if ((ath9k_hw_get_btcoex_scheme(ah) != ATH_BTCOEX_CFG_NONE) && + !ah->btcoex_hw.enabled) { + if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_MCI)) + ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT, + AR_STOMP_LOW_WLAN_WGHT); + ath9k_hw_btcoex_enable(ah); + +- if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE) ++ if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_3WIRE) + ath9k_btcoex_timer_resume(sc); + } + +@@ -1194,9 +1194,10 @@ static void ath9k_stop(struct ieee80211_ + /* Ensure HW is awake when we try to shut it down. */ + ath9k_ps_wakeup(sc); + +- if (ah->btcoex_hw.enabled) { ++ if (ah->btcoex_hw.enabled && ++ ath9k_hw_get_btcoex_scheme(ah) != ATH_BTCOEX_CFG_NONE) { + ath9k_hw_btcoex_disable(ah); +- if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE) ++ if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_3WIRE) + ath9k_btcoex_timer_pause(sc); + ath_mci_flush_profile(&sc->btcoex.mci); + } +--- a/drivers/net/wireless/ath/ath9k/gpio.c ++++ b/drivers/net/wireless/ath/ath9k/gpio.c +@@ -253,6 +253,9 @@ int ath_init_btcoex_timer(struct ath_sof + { + struct ath_btcoex *btcoex = &sc->btcoex; + ++ if (ath9k_hw_get_btcoex_scheme(sc->sc_ah) == ATH_BTCOEX_CFG_NONE) ++ return 0; ++ + btcoex->btcoex_period = ATH_BTCOEX_DEF_BT_PERIOD * 1000; + btcoex->btcoex_no_stomp = (100 - ATH_BTCOEX_DEF_DUTY_CYCLE) * + btcoex->btcoex_period / 100; +@@ -286,6 +289,9 @@ void ath9k_btcoex_timer_resume(struct at + ath_dbg(ath9k_hw_common(ah), ATH_DBG_BTCOEX, + "Starting btcoex timers\n"); + ++ if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_NONE) ++ return; ++ + /* make sure duty cycle timer is also stopped when resuming */ + if (btcoex->hw_timer_enabled) + ath9k_gen_timer_stop(sc->sc_ah, btcoex->no_stomp_timer); +@@ -306,6 +312,9 @@ void ath9k_btcoex_timer_pause(struct ath + struct ath_btcoex *btcoex = &sc->btcoex; + struct ath_hw *ah = sc->sc_ah; + ++ if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_NONE) ++ return; ++ + del_timer_sync(&btcoex->period_timer); + + if (btcoex->hw_timer_enabled) +--- a/drivers/net/wireless/ath/ath9k/hw.c ++++ b/drivers/net/wireless/ath/ath9k/hw.c +@@ -1929,7 +1929,8 @@ int ath9k_hw_reset(struct ath_hw *ah, st + #endif + } + +- if (ah->btcoex_hw.enabled) ++ if (ah->btcoex_hw.enabled && ++ ath9k_hw_get_btcoex_scheme(ah) != ATH_BTCOEX_CFG_NONE) + ath9k_hw_btcoex_enable(ah); + + if (mci && mci_hw->ready) { +--- a/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c ++++ b/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c +@@ -116,6 +116,9 @@ void ath_htc_init_btcoex_work(struct ath + { + struct ath_btcoex *btcoex = &priv->btcoex; + ++ if (ath9k_hw_get_btcoex_scheme(priv->ah) == ATH_BTCOEX_CFG_NONE) ++ return; ++ + btcoex->btcoex_period = ATH_BTCOEX_DEF_BT_PERIOD; + btcoex->btcoex_no_stomp = (100 - ATH_BTCOEX_DEF_DUTY_CYCLE) * + btcoex->btcoex_period / 100; +@@ -134,6 +137,9 @@ void ath_htc_resume_btcoex_work(struct a + struct ath_btcoex *btcoex = &priv->btcoex; + struct ath_hw *ah = priv->ah; + ++ if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_NONE) ++ return; ++ + ath_dbg(ath9k_hw_common(ah), ATH_DBG_BTCOEX, "Starting btcoex work\n"); + + btcoex->bt_priority_cnt = 0; +@@ -148,6 +154,9 @@ void ath_htc_resume_btcoex_work(struct a + */ + void ath_htc_cancel_btcoex_work(struct ath9k_htc_priv *priv) + { ++ if (ath9k_hw_get_btcoex_scheme(priv->ah) == ATH_BTCOEX_CFG_NONE) ++ return; ++ + cancel_delayed_work_sync(&priv->coex_period_work); + cancel_delayed_work_sync(&priv->duty_cycle_work); + } +--- a/drivers/net/wireless/ath/ath9k/btcoex.c ++++ b/drivers/net/wireless/ath/ath9k/btcoex.c +@@ -68,6 +68,9 @@ void ath9k_hw_init_btcoex_hw(struct ath_ + u32 i, idx; + bool rxclear_polarity = ath_bt_config.bt_rxclear_polarity; + ++ if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_NONE) ++ return; ++ + if (AR_SREV_9300_20_OR_LATER(ah)) + rxclear_polarity = !ath_bt_config.bt_rxclear_polarity; + +@@ -99,6 +102,9 @@ void ath9k_hw_btcoex_init_2wire(struct a + { + struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw; + ++ if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_NONE) ++ return; ++ + /* connect bt_active to baseband */ + REG_CLR_BIT(ah, AR_GPIO_INPUT_EN_VAL, + (AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_DEF | +@@ -121,6 +127,9 @@ void ath9k_hw_btcoex_init_3wire(struct a + { + struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw; + ++ if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_NONE) ++ return; ++ + /* btcoex 3-wire */ + REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, + (AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_BB | +@@ -147,6 +156,9 @@ static void ath9k_hw_btcoex_enable_2wire + { + struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw; + ++ if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_NONE) ++ return; ++ + /* Configure the desired GPIO port for TX_FRAME output */ + ath9k_hw_cfg_output(ah, btcoex_hw->wlanactive_gpio, + AR_GPIO_OUTPUT_MUX_AS_TX_FRAME); +@@ -158,6 +170,9 @@ void ath9k_hw_btcoex_set_weight(struct a + { + struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw; + ++ if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_NONE) ++ return; ++ + btcoex_hw->bt_coex_weights = SM(bt_weight, AR_BTCOEX_BT_WGHT) | + SM(wlan_weight, AR_BTCOEX_WL_WGHT); + } +@@ -219,9 +234,9 @@ void ath9k_hw_btcoex_enable(struct ath_h + { + struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw; + +- switch (btcoex_hw->scheme) { ++ switch (ath9k_hw_get_btcoex_scheme(ah)) { + case ATH_BTCOEX_CFG_NONE: +- break; ++ return; + case ATH_BTCOEX_CFG_2WIRE: + ath9k_hw_btcoex_enable_2wire(ah); + break; +@@ -246,6 +261,9 @@ void ath9k_hw_btcoex_disable(struct ath_ + struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw; + int i; + ++ if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_NONE) ++ return; ++ + btcoex_hw->enabled = false; + if (btcoex_hw->scheme == ATH_BTCOEX_CFG_MCI) { + ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_NONE); +@@ -294,6 +312,9 @@ static void ar9003_btcoex_bt_stomp(struc + void ath9k_hw_btcoex_bt_stomp(struct ath_hw *ah, + enum ath_stomp_type stomp_type) + { ++ if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_NONE) ++ return; ++ + if (AR_SREV_9300_20_OR_LATER(ah)) { + ar9003_btcoex_bt_stomp(ah, stomp_type); + return; +--- a/drivers/net/wireless/ath/ath9k/ar9003_mci.c ++++ b/drivers/net/wireless/ath/ath9k/ar9003_mci.c +@@ -85,6 +85,9 @@ void ar9003_mci_remote_reset(struct ath_ + { + u32 payload[4] = { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffff00}; + ++ if (!ATH9K_HW_CAP_MCI) ++ return; ++ + ar9003_mci_send_message(ah, MCI_REMOTE_RESET, 0, payload, 16, + wait_done, false); + udelay(5); +@@ -94,6 +97,9 @@ void ar9003_mci_send_lna_transfer(struct + { + u32 payload = 0x00000000; + ++ if (!ATH9K_HW_CAP_MCI) ++ return; ++ + ar9003_mci_send_message(ah, MCI_LNA_TRANS, 0, &payload, 1, + wait_done, false); + } +@@ -107,6 +113,9 @@ static void ar9003_mci_send_req_wake(str + + void ar9003_mci_send_sys_waking(struct ath_hw *ah, bool wait_done) + { ++ if (!ATH9K_HW_CAP_MCI) ++ return; ++ + ar9003_mci_send_message(ah, MCI_SYS_WAKING, MCI_FLAG_DISABLE_TIMESTAMP, + NULL, 0, wait_done, false); + } +@@ -221,6 +230,9 @@ void ar9003_mci_send_coex_halt_bt_gpm(st + struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; + u32 payload[4] = {0, 0, 0, 0}; + ++ if (!ATH9K_HW_CAP_MCI) ++ return; ++ + ath_dbg(common, ATH_DBG_MCI, "MCI Send Coex %s BT GPM.\n", + (halt) ? "halt" : "unhalt"); + +@@ -381,12 +393,17 @@ static void ar9003_mci_prep_interface(st + + void ar9003_mci_disable_interrupt(struct ath_hw *ah) + { ++ if (!ATH9K_HW_CAP_MCI) ++ return; ++ + REG_WRITE(ah, AR_MCI_INTERRUPT_EN, 0); + REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_EN, 0); + } + + void ar9003_mci_enable_interrupt(struct ath_hw *ah) + { ++ if (!ATH9K_HW_CAP_MCI) ++ return; + + REG_WRITE(ah, AR_MCI_INTERRUPT_EN, AR_MCI_INTERRUPT_DEFAULT); + REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_EN, +@@ -397,6 +414,9 @@ bool ar9003_mci_check_int(struct ath_hw + { + u32 intr; + ++ if (!ATH9K_HW_CAP_MCI) ++ return false; ++ + intr = REG_READ(ah, AR_MCI_INTERRUPT_RX_MSG_RAW); + return ((intr & ints) == ints); + } +@@ -405,6 +425,10 @@ void ar9003_mci_get_interrupt(struct ath + u32 *rx_msg_intr) + { + struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; ++ ++ if (!ATH9K_HW_CAP_MCI) ++ return; ++ + *raw_intr = mci->raw_intr; + *rx_msg_intr = mci->rx_msg_intr; + +@@ -418,6 +442,9 @@ void ar9003_mci_2g5g_changed(struct ath_ + { + struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; + ++ if (!ATH9K_HW_CAP_MCI) ++ return; ++ + if (!mci->update_2g5g && + (mci->is_2g != is_2g)) + mci->update_2g5g = true; +@@ -531,6 +558,9 @@ void ar9003_mci_reset(struct ath_hw *ah, + struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; + u32 regval, thresh; + ++ if (!ATH9K_HW_CAP_MCI) ++ return; ++ + ath_dbg(common, ATH_DBG_MCI, "MCI full_sleep = %d, is_2g = %d\n", + is_full_sleep, is_2g); + +@@ -661,6 +691,9 @@ void ar9003_mci_mute_bt(struct ath_hw *a + { + struct ath_common *common = ath9k_hw_common(ah); + ++ if (!ATH9K_HW_CAP_MCI) ++ return; ++ + /* disable all MCI messages */ + REG_WRITE(ah, AR_MCI_MSG_ATTRIBUTES_TABLE, 0xffff0000); + REG_WRITE(ah, AR_BTCOEX_WL_WEIGHTS0, 0xffffffff); +@@ -693,6 +726,9 @@ void ar9003_mci_sync_bt_state(struct ath + struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; + u32 cur_bt_state; + ++ if (!ATH9K_HW_CAP_MCI) ++ return; ++ + cur_bt_state = ar9003_mci_state(ah, MCI_STATE_REMOTE_SLEEP, NULL); + + if (mci->bt_state != cur_bt_state) { +@@ -857,6 +893,9 @@ void ar9003_mci_2g5g_switch(struct ath_h + struct ath_common *common = ath9k_hw_common(ah); + struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; + ++ if (!ATH9K_HW_CAP_MCI) ++ return; ++ + if (mci->update_2g5g) { + if (mci->is_2g) { + +@@ -908,6 +947,9 @@ bool ar9003_mci_send_message(struct ath_ + u32 saved_mci_int_en; + int i; + ++ if (!ATH9K_HW_CAP_MCI) ++ return false; ++ + saved_mci_int_en = REG_READ(ah, AR_MCI_INTERRUPT_EN); + regval = REG_READ(ah, AR_BTCOEX_CTRL); + +@@ -973,6 +1015,9 @@ void ar9003_mci_setup(struct ath_hw *ah, + struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; + void *sched_buf = (void *)((char *) gpm_buf + (sched_addr - gpm_addr)); + ++ if (!ATH9K_HW_CAP_MCI) ++ return; ++ + mci->gpm_addr = gpm_addr; + mci->gpm_buf = gpm_buf; + mci->gpm_len = len; +@@ -987,6 +1032,9 @@ void ar9003_mci_cleanup(struct ath_hw *a + { + struct ath_common *common = ath9k_hw_common(ah); + ++ if (!ATH9K_HW_CAP_MCI) ++ return; ++ + /* Turn off MCI and Jupiter mode. */ + REG_WRITE(ah, AR_BTCOEX_CTRL, 0x00); + ath_dbg(common, ATH_DBG_MCI, "MCI ar9003_mci_cleanup\n"); +@@ -1056,6 +1104,9 @@ u32 ar9003_mci_wait_for_gpm(struct ath_h + u8 recv_type = 0, recv_opcode = 0; + bool b_is_bt_cal_done = (gpm_type == MCI_GPM_BT_CAL_DONE); + ++ if (!ATH9K_HW_CAP_MCI) ++ return 0; ++ + more_data = time_out ? MCI_GPM_NOMORE : MCI_GPM_MORE; + + while (time_out > 0) { +@@ -1188,6 +1239,9 @@ u32 ar9003_mci_state(struct ath_hw *ah, + u32 value = 0, more_gpm = 0, gpm_ptr; + u8 query_type; + ++ if (!ATH9K_HW_CAP_MCI) ++ return 0; ++ + switch (state_type) { + case MCI_STATE_ENABLE: + if (mci->ready) { +--- a/drivers/net/wireless/ath/ath9k/mci.c ++++ b/drivers/net/wireless/ath/ath9k/mci.c +@@ -425,6 +425,9 @@ int ath_mci_setup(struct ath_softc *sc) + struct ath_mci_coex *mci = &sc->mci_coex; + int error = 0; + ++ if (!ATH9K_HW_CAP_MCI) ++ return 0; ++ + mci->sched_buf.bf_len = ATH_MCI_SCHED_BUF_SIZE + ATH_MCI_GPM_BUF_SIZE; + + if (ath_mci_buf_alloc(sc, &mci->sched_buf)) { +@@ -458,6 +461,9 @@ void ath_mci_cleanup(struct ath_softc *s + struct ath_hw *ah = sc->sc_ah; + struct ath_mci_coex *mci = &sc->mci_coex; + ++ if (!ATH9K_HW_CAP_MCI) ++ return; ++ + /* + * both schedule and gpm buffers will be released + */ +@@ -476,6 +482,9 @@ void ath_mci_intr(struct ath_softc *sc) + u32 more_data = MCI_GPM_MORE; + bool skip_gpm = false; + ++ if (!ATH9K_HW_CAP_MCI) ++ return; ++ + ar9003_mci_get_interrupt(sc->sc_ah, &mci_int, &mci_int_rxmsg); + + if (ar9003_mci_state(ah, MCI_STATE_ENABLE, NULL) == 0) { diff --git a/package/mac80211/patches/580-ath9k_extra_leds.patch b/package/mac80211/patches/580-ath9k_extra_leds.patch new file mode 100644 index 0000000000..a079607241 --- /dev/null +++ b/package/mac80211/patches/580-ath9k_extra_leds.patch @@ -0,0 +1,258 @@ +--- a/drivers/net/wireless/ath/ath9k/ath9k.h ++++ b/drivers/net/wireless/ath/ath9k/ath9k.h +@@ -474,6 +474,9 @@ void ath9k_btcoex_timer_pause(struct ath + #ifdef CONFIG_MAC80211_LEDS + void ath_init_leds(struct ath_softc *sc); + void ath_deinit_leds(struct ath_softc *sc); ++int ath_create_gpio_led(struct ath_softc *sc, int gpio, const char *name, ++ const char *trigger, bool active_low); ++ + #else + static inline void ath_init_leds(struct ath_softc *sc) + { +@@ -594,6 +597,13 @@ struct ath9k_vif_iter_data { + int nothers; /* number of vifs not specified above. */ + }; + ++struct ath_led { ++ struct list_head list; ++ struct ath_softc *sc; ++ const struct gpio_led *gpio; ++ struct led_classdev cdev; ++}; ++ + struct ath_softc { + struct ieee80211_hw *hw; + struct device *dev; +@@ -637,9 +647,8 @@ struct ath_softc { + struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS]; + + #ifdef CONFIG_MAC80211_LEDS +- bool led_registered; +- char led_name[32]; +- struct led_classdev led_cdev; ++ const char *led_default_trigger; ++ struct list_head leds; + #endif + + struct ath9k_hw_cal_data caldata; +--- a/drivers/net/wireless/ath/ath9k/gpio.c ++++ b/drivers/net/wireless/ath/ath9k/gpio.c +@@ -24,22 +24,89 @@ + static void ath_led_brightness(struct led_classdev *led_cdev, + enum led_brightness brightness) + { +- struct ath_softc *sc = container_of(led_cdev, struct ath_softc, led_cdev); +- ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, (brightness == LED_OFF)); ++ struct ath_led *led = container_of(led_cdev, struct ath_led, cdev); ++ struct ath_softc *sc = led->sc; ++ ++ ath9k_ps_wakeup(sc); ++ ath9k_hw_set_gpio(sc->sc_ah, led->gpio->gpio, ++ (brightness != LED_OFF) ^ led->gpio->active_low); ++ ath9k_ps_restore(sc); ++} ++ ++static int ath_add_led(struct ath_softc *sc, struct ath_led *led) ++{ ++ const struct gpio_led *gpio = led->gpio; ++ int ret; ++ ++ led->cdev.name = gpio->name; ++ led->cdev.default_trigger = gpio->default_trigger; ++ led->cdev.brightness_set = ath_led_brightness; ++ ++ ret = led_classdev_register(wiphy_dev(sc->hw->wiphy), &led->cdev); ++ if (ret < 0) ++ return ret; ++ ++ led->sc = sc; ++ list_add(&led->list, &sc->leds); ++ ++ /* Configure gpio for output */ ++ ath9k_hw_cfg_output(sc->sc_ah, gpio->gpio, ++ AR_GPIO_OUTPUT_MUX_AS_OUTPUT); ++ ++ /* LED off */ ++ ath9k_hw_set_gpio(sc->sc_ah, gpio->gpio, gpio->active_low); ++ ++ return 0; ++} ++ ++int ath_create_gpio_led(struct ath_softc *sc, int gpio_num, const char *name, ++ const char *trigger, bool active_low) ++{ ++ struct ath_led *led; ++ struct gpio_led *gpio; ++ char *_name; ++ int ret; ++ ++ led = kzalloc(sizeof(*led) + sizeof(*gpio) + strlen(name) + 1, ++ GFP_KERNEL); ++ if (!led) ++ return -ENOMEM; ++ ++ led->gpio = gpio = (struct gpio_led *) (led + 1); ++ _name = (char *) (led->gpio + 1); ++ ++ strcpy(_name, name); ++ gpio->name = _name; ++ gpio->gpio = gpio_num; ++ gpio->active_low = active_low; ++ gpio->default_trigger = trigger; ++ ++ ret = ath_add_led(sc, led); ++ if (unlikely(ret < 0)) ++ kfree(led); ++ ++ return ret; + } + + void ath_deinit_leds(struct ath_softc *sc) + { +- if (!sc->led_registered) +- return; ++ struct ath_led *led; + +- ath_led_brightness(&sc->led_cdev, LED_OFF); +- led_classdev_unregister(&sc->led_cdev); ++ while (!list_empty(&sc->leds)) { ++ led = list_first_entry(&sc->leds, struct ath_led, list); ++ list_del(&led->list); ++ ath_led_brightness(&led->cdev, LED_OFF); ++ led_classdev_unregister(&led->cdev); ++ kfree(led); ++ } + } + + void ath_init_leds(struct ath_softc *sc) + { +- int ret; ++ char led_name[32]; ++ const char *trigger; ++ ++ INIT_LIST_HEAD(&sc->leds); + + if (AR_SREV_9100(sc->sc_ah)) + return; +@@ -57,26 +124,15 @@ void ath_init_leds(struct ath_softc *sc) + sc->sc_ah->led_pin = ATH_LED_PIN_DEF; + } + +- /* Configure gpio 1 for output */ +- ath9k_hw_cfg_output(sc->sc_ah, sc->sc_ah->led_pin, +- AR_GPIO_OUTPUT_MUX_AS_OUTPUT); +- /* LED off, active low */ +- ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 1); +- +- if (!led_blink) +- sc->led_cdev.default_trigger = +- ieee80211_get_radio_led_name(sc->hw); +- +- snprintf(sc->led_name, sizeof(sc->led_name), +- "ath9k-%s", wiphy_name(sc->hw->wiphy)); +- sc->led_cdev.name = sc->led_name; +- sc->led_cdev.brightness_set = ath_led_brightness; ++ snprintf(led_name, sizeof(led_name), "ath9k-%s", ++ wiphy_name(sc->hw->wiphy)); + +- ret = led_classdev_register(wiphy_dev(sc->hw->wiphy), &sc->led_cdev); +- if (ret < 0) +- return; ++ if (led_blink) ++ trigger = sc->led_default_trigger; ++ else ++ trigger = ieee80211_get_radio_led_name(sc->hw); + +- sc->led_registered = true; ++ ath_create_gpio_led(sc, sc->sc_ah->led_pin, led_name, trigger, 1); + } + #endif + +--- a/drivers/net/wireless/ath/ath9k/init.c ++++ b/drivers/net/wireless/ath/ath9k/init.c +@@ -803,7 +803,7 @@ int ath9k_init_device(u16 devid, struct + + #ifdef CONFIG_MAC80211_LEDS + /* must be initialized before ieee80211_register_hw */ +- sc->led_cdev.default_trigger = ieee80211_create_tpt_led_trigger(sc->hw, ++ sc->led_default_trigger = ieee80211_create_tpt_led_trigger(sc->hw, + IEEE80211_TPT_LEDTRIG_FL_RADIO, ath9k_tpt_blink, + ARRAY_SIZE(ath9k_tpt_blink)); + #endif +--- a/drivers/net/wireless/ath/ath9k/debug.c ++++ b/drivers/net/wireless/ath/ath9k/debug.c +@@ -1304,6 +1304,61 @@ static const struct file_operations fops + .llseek = default_llseek, + }; + ++#ifdef CONFIG_MAC80211_LEDS ++ ++static ssize_t write_file_gpio_led(struct file *file, const char __user *ubuf, ++ size_t count, loff_t *ppos) ++{ ++ struct ath_softc *sc = file->private_data; ++ char buf[32], *str, *name, *c; ++ ssize_t len; ++ unsigned int gpio; ++ bool active_low = false; ++ ++ len = min(count, sizeof(buf) - 1); ++ if (copy_from_user(buf, ubuf, len)) ++ return -EFAULT; ++ ++ buf[len] = '\0'; ++ name = strchr(buf, ','); ++ if (!name) ++ return -EINVAL; ++ ++ *(name++) = 0; ++ if (!*name) ++ return -EINVAL; ++ ++ c = strchr(name, '\n'); ++ if (c) ++ *c = 0; ++ ++ str = buf; ++ if (*str == '!') { ++ str++; ++ active_low = true; ++ } ++ ++ if (kstrtouint(str, 0, &gpio) < 0) ++ return -EINVAL; ++ ++ if (gpio >= sc->sc_ah->caps.num_gpio_pins) ++ return -EINVAL; ++ ++ if (ath_create_gpio_led(sc, gpio, name, NULL, active_low) < 0) ++ return -EINVAL; ++ ++ return count; ++} ++ ++static const struct file_operations fops_gpio_led = { ++ .write = write_file_gpio_led, ++ .open = ath9k_debugfs_open, ++ .owner = THIS_MODULE, ++ .llseek = default_llseek, ++}; ++ ++#endif ++ + void ath9k_debug_samp_bb_mac(struct ath_softc *sc) + { + #define ATH_SAMP_DBG(c) (sc->debug.bb_mac_samp[sc->debug.sampidx].c) +@@ -1725,6 +1780,11 @@ int ath9k_init_debug(struct ath_hw *ah) + debugfs_create_file("samples", S_IRUSR, sc->debug.debugfs_phy, sc, + &fops_samps); + ++#ifdef CONFIG_MAC80211_LEDS ++ debugfs_create_file("gpio_led", S_IWUSR, ++ sc->debug.debugfs_phy, sc, &fops_gpio_led); ++#endif ++ + debugfs_create_u32("gpio_mask", S_IRUSR | S_IWUSR, + sc->debug.debugfs_phy, &sc->sc_ah->gpio_mask); + diff --git a/package/mac80211/patches/581-ath9k_extra_platform_leds.patch b/package/mac80211/patches/581-ath9k_extra_platform_leds.patch new file mode 100644 index 0000000000..3834d43881 --- /dev/null +++ b/package/mac80211/patches/581-ath9k_extra_platform_leds.patch @@ -0,0 +1,71 @@ +--- a/include/linux/ath9k_platform.h ++++ b/include/linux/ath9k_platform.h +@@ -32,6 +32,9 @@ struct ath9k_platform_data { + bool is_clk_25mhz; + int (*get_mac_revision)(void); + int (*external_reset)(void); ++ ++ int num_leds; ++ const struct gpio_led *leds; + }; + + #endif /* _LINUX_ATH9K_PLATFORM_H */ +--- a/drivers/net/wireless/ath/ath9k/gpio.c ++++ b/drivers/net/wireless/ath/ath9k/gpio.c +@@ -14,6 +14,7 @@ + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + ++#include + #include "ath9k.h" + + /********************************/ +@@ -88,6 +89,24 @@ int ath_create_gpio_led(struct ath_softc + return ret; + } + ++static int ath_create_platform_led(struct ath_softc *sc, ++ const struct gpio_led *gpio) ++{ ++ struct ath_led *led; ++ int ret; ++ ++ led = kzalloc(sizeof(*led), GFP_KERNEL); ++ if (!led) ++ return -ENOMEM; ++ ++ led->gpio = gpio; ++ ret = ath_add_led(sc, led); ++ if (ret < 0) ++ kfree(led); ++ ++ return ret; ++} ++ + void ath_deinit_leds(struct ath_softc *sc) + { + struct ath_led *led; +@@ -103,8 +122,10 @@ void ath_deinit_leds(struct ath_softc *s + + void ath_init_leds(struct ath_softc *sc) + { ++ struct ath9k_platform_data *pdata = sc->dev->platform_data; + char led_name[32]; + const char *trigger; ++ int i; + + INIT_LIST_HEAD(&sc->leds); + +@@ -133,6 +154,12 @@ void ath_init_leds(struct ath_softc *sc) + trigger = ieee80211_get_radio_led_name(sc->hw); + + ath_create_gpio_led(sc, sc->sc_ah->led_pin, led_name, trigger, 1); ++ ++ if (!pdata) ++ return; ++ ++ for (i = 0; i < pdata->num_leds; i++) ++ ath_create_platform_led(sc, &pdata->leds[i]); + } + #endif + diff --git a/package/mac80211/patches/604-rt2x00-add-CONFIG_RT2X00_LIB_EEPROM-option.patch b/package/mac80211/patches/604-rt2x00-add-CONFIG_RT2X00_LIB_EEPROM-option.patch index 25709b85b1..3d2b9b80fe 100644 --- a/package/mac80211/patches/604-rt2x00-add-CONFIG_RT2X00_LIB_EEPROM-option.patch +++ b/package/mac80211/patches/604-rt2x00-add-CONFIG_RT2X00_LIB_EEPROM-option.patch @@ -1,6 +1,6 @@ --- a/config.mk +++ b/config.mk -@@ -567,6 +567,7 @@ CONFIG_RT2X00=y +@@ -606,6 +606,7 @@ CONFIG_RT2X00=y CONFIG_RT2X00_LIB=m CONFIG_RT2800_LIB=m CONFIG_RT2X00_LIB_FIRMWARE=y diff --git a/package/mac80211/patches/850-p54spi-lock-fix.patch b/package/mac80211/patches/850-p54spi-lock-fix.patch deleted file mode 100644 index d19ba61702..0000000000 --- a/package/mac80211/patches/850-p54spi-lock-fix.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- a/drivers/net/wireless/p54/p54spi.c -+++ b/drivers/net/wireless/p54/p54spi.c -@@ -656,6 +656,7 @@ static int __devinit p54spi_probe(struct - init_completion(&priv->fw_comp); - INIT_LIST_HEAD(&priv->tx_pending); - mutex_init(&priv->mutex); -+ spin_lock_init(&priv->tx_lock); - SET_IEEE80211_DEV(hw, &spi->dev); - priv->common.open = p54spi_op_start; - priv->common.stop = p54spi_op_stop; diff --git a/package/mac80211/patches/851-p54spi-mutex-fix.patch b/package/mac80211/patches/851-p54spi-mutex-fix.patch deleted file mode 100644 index e974e9ddae..0000000000 --- a/package/mac80211/patches/851-p54spi-mutex-fix.patch +++ /dev/null @@ -1,15 +0,0 @@ ---- a/drivers/net/wireless/p54/p54spi.c -+++ b/drivers/net/wireless/p54/p54spi.c -@@ -581,11 +581,7 @@ static void p54spi_op_stop(struct ieee80 - struct p54s_priv *priv = dev->priv; - unsigned long flags; - -- if (mutex_lock_interruptible(&priv->mutex)) { -- /* FIXME: how to handle this error? */ -- return; -- } -- -+ mutex_lock(&priv->mutex); - WARN_ON(priv->fw_state != FW_STATE_READY); - - cancel_work_sync(&priv->work); diff --git a/package/mac80211/patches/852-p54spi-cancel-workqueue-fix.patch b/package/mac80211/patches/852-p54spi-cancel-workqueue-fix.patch deleted file mode 100644 index f8d36ca049..0000000000 --- a/package/mac80211/patches/852-p54spi-cancel-workqueue-fix.patch +++ /dev/null @@ -1,20 +0,0 @@ ---- a/drivers/net/wireless/p54/p54spi.c -+++ b/drivers/net/wireless/p54/p54spi.c -@@ -584,8 +584,6 @@ static void p54spi_op_stop(struct ieee80 - mutex_lock(&priv->mutex); - WARN_ON(priv->fw_state != FW_STATE_READY); - -- cancel_work_sync(&priv->work); -- - p54spi_power_off(priv); - spin_lock_irqsave(&priv->tx_lock, flags); - INIT_LIST_HEAD(&priv->tx_pending); -@@ -593,6 +591,8 @@ static void p54spi_op_stop(struct ieee80 - - priv->fw_state = FW_STATE_OFF; - mutex_unlock(&priv->mutex); -+ -+ cancel_work_sync(&priv->work); - } - - static int __devinit p54spi_probe(struct spi_device *spi) diff --git a/package/mac80211/patches/910-fix-reversed-warn-on-workqueue.patch b/package/mac80211/patches/910-fix-reversed-warn-on-workqueue.patch deleted file mode 100644 index b5985741ca..0000000000 --- a/package/mac80211/patches/910-fix-reversed-warn-on-workqueue.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/compat/compat-2.6.36.c -+++ b/compat/compat-2.6.36.c -@@ -101,7 +101,7 @@ EXPORT_SYMBOL_GPL(system_nrt_wq); - void compat_system_workqueue_create() - { - system_nrt_wq = create_singlethread_workqueue("events_nrt"); -- WARN_ON(system_nrt_wq); -+ WARN_ON(!system_nrt_wq); - } - - void compat_system_workqueue_destroy() diff --git a/target/linux/ar71xx/files/include/linux/ath9k_platform.h b/target/linux/ar71xx/files/include/linux/ath9k_platform.h index 020387a114..b37d23d834 100644 --- a/target/linux/ar71xx/files/include/linux/ath9k_platform.h +++ b/target/linux/ar71xx/files/include/linux/ath9k_platform.h @@ -28,6 +28,13 @@ struct ath9k_platform_data { int led_pin; u32 gpio_mask; u32 gpio_val; + + bool is_clk_25mhz; + int (*get_mac_revision)(void); + int (*external_reset)(void); + + int num_leds; + const struct gpio_led *leds; }; #endif /* _LINUX_ATH9K_PLATFORM_H */