From cb3397c55a834cfa9505b79185707bd5f89ad9c1 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sun, 20 Nov 2011 12:04:29 +0000 Subject: [PATCH] mac80211: update to 2011-11-15 from trunk SVN-Revision: 29275 --- package/mac80211/Makefile | 37 +- .../mac80211/patches/001-disable_b44.patch | 2 +- .../mac80211/patches/002-disable_rfkill.patch | 2 +- .../patches/005-disable_ssb_build.patch | 6 +- .../patches/006-disable_bcma_build.patch | 2 +- .../patches/007-remove_misc_drivers.patch | 4 +- package/mac80211/patches/010-no_pcmcia.patch | 2 +- package/mac80211/patches/011-no_sdio.patch | 2 +- .../patches/013-disable_b43_nphy.patch | 6 +- .../patches/015-remove-rt2x00-options.patch | 4 +- .../patches/050-compat_firmware.patch | 9 +- .../patches/051-compat_workqueue.patch | 18 + .../patches/100-disable_pcmcia_compat.patch | 2 +- .../patches/110-disable_usb_compat.patch | 2 +- .../patches/120-pr_fmt_warnings.patch | 2 +- .../patches/140-mesh_pathtbl_backport.patch | 2 +- .../mac80211/patches/300-pending_work.patch | 3309 ++++------------- package/mac80211/patches/310-ibss_ht.patch | 720 ---- .../patches/400-ath_move_debug_code.patch | 2 +- .../patches/402-ath9k_blink_default.patch | 2 +- ...h9k-fix-invalid-mac-address-handling.patch | 6 +- .../patches/404-ath_regd_optional.patch | 12 +- .../patches/405-world_regd_fixup.patch | 4 +- .../patches/406-regd_no_assoc_hints.patch | 4 +- .../410-ath9k_allow_adhoc_and_ap.patch | 4 +- .../411-ath5k_allow_adhoc_and_ap.patch | 4 +- .../patches/500-ath9k_eeprom_debugfs.patch | 4 +- .../510-ath9k_intr_mitigation_tweak.patch | 2 +- .../patches/511-ath9k_increase_bcbuf.patch | 4 +- .../patches/512-ath9k_reduce_rxbuf.patch | 2 +- .../patches/513-ath9k_channelbw_debugfs.patch | 86 +- .../520-mac80211_minstrel_ht_aggr_delay.patch | 6 +- .../521-mac80211_ht_change_rate_update.patch | 4 +- .../522-mac80211_reduce_txqueuelen.patch | 2 +- ...e.patch => 523-minstrel_ht_optimize.patch} | 18 +- .../patches/530-mac80211_cur_txpower.patch | 6 +- .../patches/531-ath9k_cur_txpower.patch | 8 +- .../patches/540-ath9k_limit_qlen.patch | 22 +- .../patches/541-ath9k_sw_retry_reduce.patch | 18 +- ...atch => 542-ath9k_ar9280_cold_reset.patch} | 2 +- .../550-ath9k_debug_remove_packet_rssi.patch | 70 + .../551-ath9k_fix_keymiss_handling.patch | 93 - .../551-ath9k_per_chain_signal_strength.patch | 374 ++ .../patches/552-ath9k_fix_phyerror.patch | 37 - .../patches/561-mac80211_tx_status.patch | 96 - .../patches/562-ath9k_tx_status.patch | 121 - .../570-ath9k_tx_stop_failure_debug.patch | 27 - .../patches/571-ath9k_reset_debug.patch | 124 - .../patches/572-ath9k_fix_tx_retry.patch | 41 - .../patches/573-ath9k_fix_tx_flush_bar.patch | 51 - .../580-ath9k_cleanup_set_interrupt.patch | 155 - .../581-ath9k_cleanup_txpower_handling.patch | 627 ---- .../582-ath9k_remove_current_rd_ext.patch | 34 - .../patches/583-ath9k_remove_eep_reg_1.patch | 54 - .../603-rt2x00-introduce-rt2x00eeprom.patch | 12 +- ...-add-CONFIG_RT2X00_LIB_EEPROM-option.patch | 2 +- .../patches/605-rt2x00-pci-eeprom.patch | 46 + ...700-mwl8k-missing-pci-id-for-WNR854T.patch | 2 +- .../800-b43-gpio-mask-module-option.patch | 4 +- package/mac80211/patches/810-b43_no_pio.patch | 2 +- .../patches/820-b43-add-antenna-control.patch | 131 + .../patches/850-p54spi-lock-fix.patch | 10 + .../patches/851-p54spi-mutex-fix.patch | 15 + .../852-p54spi-cancel-workqueue-fix.patch | 20 + 64 files changed, 1601 insertions(+), 4900 deletions(-) create mode 100644 package/mac80211/patches/051-compat_workqueue.patch delete mode 100644 package/mac80211/patches/310-ibss_ht.patch rename package/mac80211/patches/{560-minstrel_ht_optimize.patch => 523-minstrel_ht_optimize.patch} (89%) rename package/mac80211/patches/{550-ath9k_ar9280_cold_reset.patch => 542-ath9k_ar9280_cold_reset.patch} (91%) create mode 100644 package/mac80211/patches/550-ath9k_debug_remove_packet_rssi.patch delete mode 100644 package/mac80211/patches/551-ath9k_fix_keymiss_handling.patch create mode 100644 package/mac80211/patches/551-ath9k_per_chain_signal_strength.patch delete mode 100644 package/mac80211/patches/552-ath9k_fix_phyerror.patch delete mode 100644 package/mac80211/patches/561-mac80211_tx_status.patch delete mode 100644 package/mac80211/patches/562-ath9k_tx_status.patch delete mode 100644 package/mac80211/patches/570-ath9k_tx_stop_failure_debug.patch delete mode 100644 package/mac80211/patches/571-ath9k_reset_debug.patch delete mode 100644 package/mac80211/patches/572-ath9k_fix_tx_retry.patch delete mode 100644 package/mac80211/patches/573-ath9k_fix_tx_flush_bar.patch delete mode 100644 package/mac80211/patches/580-ath9k_cleanup_set_interrupt.patch delete mode 100644 package/mac80211/patches/581-ath9k_cleanup_txpower_handling.patch delete mode 100644 package/mac80211/patches/582-ath9k_remove_current_rd_ext.patch delete mode 100644 package/mac80211/patches/583-ath9k_remove_eep_reg_1.patch create mode 100644 package/mac80211/patches/605-rt2x00-pci-eeprom.patch create mode 100644 package/mac80211/patches/820-b43-add-antenna-control.patch create mode 100644 package/mac80211/patches/850-p54spi-lock-fix.patch create mode 100644 package/mac80211/patches/851-p54spi-mutex-fix.patch create mode 100644 package/mac80211/patches/852-p54spi-cancel-workqueue-fix.patch diff --git a/package/mac80211/Makefile b/package/mac80211/Makefile index 73a267fa39..35c2fa3db0 100644 --- a/package/mac80211/Makefile +++ b/package/mac80211/Makefile @@ -10,10 +10,10 @@ include $(INCLUDE_DIR)/kernel.mk PKG_NAME:=mac80211 -PKG_VERSION:=2011-09-14 +PKG_VERSION:=2011-11-15 PKG_RELEASE:=1 PKG_SOURCE_URL:=http://mirror2.openwrt.org/sources -PKG_MD5SUM:=a5627e6079e8d0f0baf7045141503a3d +PKG_MD5SUM:=0bb667c7fecbc244840d806df0604661 PKG_SOURCE:=compat-wireless-$(PKG_VERSION).tar.bz2 PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/compat-wireless-$(PKG_VERSION) @@ -412,7 +412,7 @@ define KernelPackage/ath9k-common $(call KernelPackage/mac80211/Default) TITLE:=Atheros 802.11n wireless devices (common code for ath9k and ath9k_htc) URL:=http://linuxwireless.org/en/users/Drivers/ath9k - DEPENDS+= @PCI_SUPPORT||TARGET_ar71xx +kmod-ath +@DRIVER_11N_SUPPORT + DEPENDS+= @PCI_SUPPORT||USB_SUPPORT||TARGET_ar71xx +kmod-ath +@DRIVER_11N_SUPPORT FILES:= \ $(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath9k/ath9k_common.ko \ $(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath9k/ath9k_hw.ko @@ -452,7 +452,7 @@ endef define KernelPackage/carl9170 $(call KernelPackage/mac80211/Default) TITLE:=Driver for Atheros AR9170 USB sticks - DEPENDS:=@USB_SUPPORT +kmod-mac80211 +kmod-ath +kmod-usb-core +@DRIVER_11N_SUPPORT + DEPENDS:=@USB_SUPPORT +kmod-mac80211 +kmod-ath +kmod-usb-core +kmod-input-core +@DRIVER_11N_SUPPORT FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ath/carl9170/carl9170.ko AUTOLOAD:=$(call AutoLoad,60,carl9170) endef @@ -489,7 +489,7 @@ endef define KernelPackage/libertas-usb $(call KernelPackage/mac80211/Default) - DEPENDS+= @USB_SUPPORT +kmod-mac80211 +kmod-usb-core +kmod-lib80211 + DEPENDS+= @USB_SUPPORT +kmod-cfg80211 +kmod-usb-core +kmod-lib80211 +@DRIVER_WEXT_SUPPORT TITLE:=Marvell 88W8015 Wireless Driver FILES:= \ $(PKG_BUILD_DIR)/drivers/net/wireless/libertas/libertas.ko \ @@ -499,7 +499,7 @@ endef define KernelPackage/libertas-sd $(call KernelPackage/mac80211/Default) - DEPENDS+= +kmod-mac80211 +kmod-lib80211 +@DRIVER_WEXT_SUPPORT @!LINUX_2_6_30 + DEPENDS+= +kmod-cfg80211 +kmod-lib80211 +@DRIVER_WEXT_SUPPORT TITLE:=Marvell 88W8686 Wireless Driver FILES:= \ $(PKG_BUILD_DIR)/drivers/net/wireless/libertas/libertas.ko \ @@ -518,7 +518,7 @@ endef define KernelPackage/net-libipw $(call KernelPackage/mac80211/Default) TITLE:=libipw for ipw2100 and ipw2200 - DEPENDS:=@PCI_SUPPORT +kmod-crypto-core +kmod-crypto-arc4 +kmod-crypto-aes +kmod-crypto-michael-mic +kmod-lib80211 +kmod-cfg80211 + DEPENDS:=@PCI_SUPPORT +kmod-crypto-core +kmod-crypto-arc4 +kmod-crypto-aes +kmod-crypto-michael-mic +kmod-lib80211 +kmod-cfg80211 +@DRIVER_WEXT_SUPPORT FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ipw2x00/libipw.ko AUTOLOAD:=$(call AutoLoad,49,libipw) endef @@ -591,7 +591,7 @@ endef define KernelPackage/net-hermes-pci $(call KernelPackage/mac80211/Default) TITLE:=Intersil Prism 2.5 PCI support - DEPENDS:=@PCI_SUPPORT +kmod-net-hermes +kmod-cfg80211 + DEPENDS:=@PCI_SUPPORT +kmod-net-hermes FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/orinoco/orinoco_pci.ko AUTOLOAD:=$(call AutoLoad,55,orinoco_pci) endef @@ -603,7 +603,7 @@ endef define KernelPackage/net-hermes-plx $(call KernelPackage/mac80211/Default) TITLE:=PLX9052 based PCI adaptor - DEPENDS:=@PCI_SUPPORT +kmod-net-hermes +kmod-cfg80211 + DEPENDS:=@PCI_SUPPORT +kmod-net-hermes FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/orinoco/orinoco_plx.ko AUTOLOAD:=$(call AutoLoad,55,orinoco_plx) endef @@ -615,7 +615,7 @@ endef define KernelPackage/net-hermes-pcmcia $(call KernelPackage/mac80211/Default) TITLE:=Hermes based PCMCIA adaptors - DEPENDS:=@PCMCIA_SUPPORT +kmod-net-hermes +kmod-cfg80211 @BROKEN + DEPENDS:=@PCMCIA_SUPPORT +kmod-net-hermes @BROKEN FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/orinoco/orinoco_cs.ko AUTOLOAD:=$(call AutoLoad,55,orinoco_cs) endef @@ -628,7 +628,7 @@ define KernelPackage/iwlagn $(call KernelPackage/mac80211/Default) DEPENDS:= +kmod-mac80211 @PCI_SUPPORT TITLE:=Intel AGN Wireless support - FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/iwlwifi/iwlagn.$(LINUX_KMOD_SUFFIX) + FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/iwlwifi/iwlwifi.ko AUTOLOAD:=$(call AutoLoad,60,iwlagn) MENU:=1 endef @@ -704,7 +704,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.$(LINUX_KMOD_SUFFIX) + FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/iwlegacy/iwl-legacy.ko AUTOLOAD:=$(call AutoLoad,60,iwl-legacy) endef @@ -716,7 +716,7 @@ define KernelPackage/iwl3945 $(call KernelPackage/mac80211/Default) DEPENDS:= +kmod-mac80211 +kmod-iwl-legacy TITLE:=Intel iwl3945 Wireless support - FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/iwlegacy/iwl3945.$(LINUX_KMOD_SUFFIX) + FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/iwlegacy/iwl3945.ko AUTOLOAD:=$(call AutoLoad,61,iwl3945) endef @@ -728,7 +728,7 @@ define KernelPackage/iwl4965 $(call KernelPackage/mac80211/Default) DEPENDS:= +kmod-mac80211 +kmod-iwl-legacy TITLE:=Intel iwl4965 Wireless support - FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/iwlegacy/iwl4965.$(LINUX_KMOD_SUFFIX) + FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/iwlegacy/iwl4965.ko AUTOLOAD:=$(call AutoLoad,61,iwl4965) endef @@ -1059,6 +1059,7 @@ MAKE_OPTS:= \ ARCH="$(LINUX_KARCH)" \ EXTRA_CFLAGS="$(BUILDFLAGS)" \ $(foreach opt,$(CONFOPTS),CONFIG_$(opt)=m) \ + CONFIG_CFG80211=$(if $(CONFIG_PACKAGE_kmod-cfg80211),m) \ CONFIG_MAC80211=$(if $(CONFIG_PACKAGE_kmod-mac80211),m) \ CONFIG_MAC80211_RC_MINSTREL=y \ CONFIG_MAC80211_LEDS=$(CONFIG_LEDS_TRIGGERS) \ @@ -1119,6 +1120,7 @@ MAKE_OPTS:= \ CONFIG_RT2800_LIB=$(if $(CONFIG_PACKAGE_kmod-rt2800-lib),m) \ CONFIG_RT2800PCI=$(if $(CONFIG_PACKAGE_kmod-rt2800-pci),m) \ CONFIG_RT2800USB=$(if $(CONFIG_PACKAGE_kmod-rt2800-usb),m) \ + CONFIG_RT2800USB_RT53XX=$(if $(CONFIG_PACKAGE_kmod-rt2800-usb),y) \ CONFIG_RTL8180=$(if $(CONFIG_PACKAGE_kmod-rtl8180),m) \ CONFIG_RTL8187=$(if $(CONFIG_PACKAGE_kmod-rtl8187),m) \ CONFIG_RTL8192CE= \ @@ -1139,7 +1141,7 @@ MAKE_OPTS:= \ CONFIG_LIB80211_CRYPT_WEP=$(if $(CONFIG_PACKAGE_kmod-lib80211),m) \ CONFIG_LIB80211_CRYPT_CCMP=$(if $(CONFIG_PACKAGE_kmod-lib80211),m) \ CONFIG_LIB80211_CRYPT_TKIP=$(if $(CONFIG_PACKAGE_kmod-lib80211),m) \ - CONFIG_IWLAGN=$(if $(CONFIG_PACKAGE_kmod-iwlagn),m) \ + CONFIG_IWLWIFI=$(if $(CONFIG_PACKAGE_kmod-iwlagn),m) \ CONFIG_IWLWIFI_LEGACY=$(if $(CONFIG_PACKAGE_kmod-iwl-legacy),m) \ CONFIG_COMPAT_IWL4965=$(if $(CONFIG_PACKAGE_kmod-iwl4965),m) \ CONFIG_IWL3945=$(if $(CONFIG_PACKAGE_kmod-iwl3945),m) \ @@ -1174,6 +1176,9 @@ MAKE_OPTS:= \ CONFIG_ATL2= \ CONFIG_ATL1E= \ CONFIG_ATL1C= \ + CONFIG_BRCMFMAC= \ + CONFIG_BRCMUMAC= \ + CONFIG_BRCMSMAC= \ KLIB_BUILD="$(LINUX_DIR)" \ MODPROBE=: \ KLIB=$(TARGET_MODULES_DIR) \ @@ -1197,7 +1202,7 @@ define Build/Prepare rm -f $(PKG_BUILD_DIR)/include/net/ieee80211.h endef -ifneq ($(CONFIG_PACKAGE_kmod-cfg80211),) +ifneq ($(CONFIG_PACKAGE_kmod-cfg80211)$(CONFIG_PACKAGE_kmod-lib80211),) define Build/Compile/kmod rm -rf $(PKG_BUILD_DIR)/modules $(MAKE) $(PKG_JOBS) -C "$(PKG_BUILD_DIR)" $(MAKE_OPTS) all diff --git a/package/mac80211/patches/001-disable_b44.patch b/package/mac80211/patches/001-disable_b44.patch index a4008bf1ad..547a453eac 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 -@@ -340,8 +340,8 @@ CONFIG_B43_BCMA_PIO=y +@@ -339,8 +339,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 61e8b966b7..4ba30479fa 100644 --- a/package/mac80211/patches/002-disable_rfkill.patch +++ b/package/mac80211/patches/002-disable_rfkill.patch @@ -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") -@@ -642,10 +642,10 @@ endif #CONFIG_COMPAT_KERNEL_2_6_27 +@@ -632,10 +632,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/005-disable_ssb_build.patch b/package/mac80211/patches/005-disable_ssb_build.patch index d5578d173f..ac95769059 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 -@@ -316,7 +315,8 @@ CONFIG_IPW2200_QOS=y +@@ -315,7 +314,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 -@@ -329,7 +329,7 @@ endif #CONFIG_PCMCIA +@@ -328,7 +328,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 -@@ -538,7 +538,6 @@ endif #CONFIG_SPI_MASTER end of SPI driv +@@ -535,7 +535,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 17eff65383..8a82d7ed96 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 -@@ -331,12 +331,12 @@ CONFIG_SSB_DRIVER_PCICORE=y +@@ -330,12 +330,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 103eb7b60a..0b4b26ef57 100644 --- a/package/mac80211/patches/007-remove_misc_drivers.patch +++ b/package/mac80211/patches/007-remove_misc_drivers.patch @@ -9,7 +9,7 @@ endif #CONFIG_STAGING # mac80211 test driver -@@ -368,13 +368,13 @@ endif #CONFIG_CRC_ITU_T +@@ -367,13 +367,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 -@@ -435,21 +435,21 @@ endif #CONFIG_COMPAT_KERNEL_2_6_29 +@@ -432,21 +432,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/010-no_pcmcia.patch b/package/mac80211/patches/010-no_pcmcia.patch index d6246b782a..f6b89d86bc 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 -@@ -248,7 +248,7 @@ CONFIG_B43=m +@@ -247,7 +247,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 366488a4ad..fc2e6d9b60 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 -@@ -521,7 +521,7 @@ endif #CONFIG_SPI_MASTER end of SPI driv +@@ -518,7 +518,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 8baaaca7c4..f9f13e21bd 100644 --- a/package/mac80211/patches/013-disable_b43_nphy.patch +++ b/package/mac80211/patches/013-disable_b43_nphy.patch @@ -1,11 +1,13 @@ --- a/config.mk +++ b/config.mk -@@ -254,7 +254,7 @@ ifdef CONFIG_MAC80211_LEDS +@@ -253,8 +253,8 @@ ifdef CONFIG_MAC80211_LEDS CONFIG_B43_LEDS=y endif #CONFIG_MAC80211_LEDS CONFIG_B43_PHY_LP=y -CONFIG_B43_PHY_N=y +-CONFIG_B43_PHY_HT=y +# CONFIG_B43_PHY_N=y - # CONFIG_B43_PHY_HT=y ++# CONFIG_B43_PHY_HT=y # CONFIG_B43_PHY_LCN=y # CONFIG_B43_FORCE_PIO=y + # CONFIG_B43_DEBUG=y diff --git a/package/mac80211/patches/015-remove-rt2x00-options.patch b/package/mac80211/patches/015-remove-rt2x00-options.patch index e449c23ef8..18490c584a 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 -@@ -330,7 +330,7 @@ CONFIG_RTL8180=m +@@ -329,7 +329,7 @@ CONFIG_RTL8180=m CONFIG_ADM8211=m @@ -9,7 +9,7 @@ CONFIG_RT2400PCI=m CONFIG_RT2500PCI=m ifdef CONFIG_CRC_CCITT -@@ -470,7 +470,7 @@ CONFIG_RT2800USB_RT35XX=y +@@ -467,7 +467,7 @@ CONFIG_RT2800USB_RT35XX=y # CONFIG_RT2800USB_RT53XX=y CONFIG_RT2800USB_UNKNOWN=y endif #CONFIG_CRC_CCITT diff --git a/package/mac80211/patches/050-compat_firmware.patch b/package/mac80211/patches/050-compat_firmware.patch index f4cc27d405..c51c672139 100644 --- a/package/mac80211/patches/050-compat_firmware.patch +++ b/package/mac80211/patches/050-compat_firmware.patch @@ -59,7 +59,7 @@ static int __init compat_init(void) { /* pm-qos for kernels <= 2.6.24, this is a no-op on newer kernels */ -@@ -45,15 +56,15 @@ static int __init compat_init(void) +@@ -46,7 +57,8 @@ static int __init compat_init(void) COMPAT_BASE_TREE " " COMPAT_BASE_TREE_VERSION "\n"); @@ -69,12 +69,13 @@ } module_init(compat_init); - static void __exit compat_exit(void) - { +@@ -55,7 +67,8 @@ static void __exit compat_exit(void) compat_pm_qos_power_deinit(); -- + compat_system_workqueue_destroy(); + - return; + firmware_class_exit(); ++ return; } module_exit(compat_exit); diff --git a/package/mac80211/patches/051-compat_workqueue.patch b/package/mac80211/patches/051-compat_workqueue.patch new file mode 100644 index 0000000000..d94507db71 --- /dev/null +++ b/package/mac80211/patches/051-compat_workqueue.patch @@ -0,0 +1,18 @@ +--- 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/100-disable_pcmcia_compat.patch b/package/mac80211/patches/100-disable_pcmcia_compat.patch index 99f250ab3c..52979ad880 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 -@@ -65,9 +65,9 @@ static inline struct sk_buff *netdev_all +@@ -68,9 +68,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 7678e3bbbc..7318cf935d 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 -@@ -456,7 +456,7 @@ endif #CONFIG_COMPAT_KERNEL_2_6_29 +@@ -453,7 +453,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 920398e501..53add829ba 100644 --- a/package/mac80211/patches/120-pr_fmt_warnings.patch +++ b/package/mac80211/patches/120-pr_fmt_warnings.patch @@ -147,7 +147,7 @@ +#undef pr_fmt #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include + #include --- a/drivers/net/wireless/libertas/mesh.c +++ b/drivers/net/wireless/libertas/mesh.c @@ -1,3 +1,4 @@ diff --git a/package/mac80211/patches/140-mesh_pathtbl_backport.patch b/package/mac80211/patches/140-mesh_pathtbl_backport.patch index aae5559e86..2a3591373d 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 -@@ -844,7 +844,6 @@ static void table_flush_by_iface(struct +@@ -841,7 +841,6 @@ static void table_flush_by_iface(struct struct hlist_node *p; int i; diff --git a/package/mac80211/patches/300-pending_work.patch b/package/mac80211/patches/300-pending_work.patch index d3bcece60d..e86505368d 100644 --- a/package/mac80211/patches/300-pending_work.patch +++ b/package/mac80211/patches/300-pending_work.patch @@ -1,2166 +1,652 @@ ---- a/drivers/net/wireless/ath/ath9k/ar9002_mac.c -+++ b/drivers/net/wireless/ath/ath9k/ar9002_mac.c -@@ -170,33 +170,104 @@ static bool ar9002_hw_get_isr(struct ath - return true; - } - --static void ar9002_hw_fill_txdesc(struct ath_hw *ah, void *ds, u32 seglen, -- bool is_firstseg, bool is_lastseg, -- const void *ds0, dma_addr_t buf_addr, -- unsigned int qcu) -+static void -+ar9002_set_txdesc(struct ath_hw *ah, void *ds, struct ath_tx_info *i) - { - struct ar5416_desc *ads = AR5416DESC(ds); -+ u32 ctl1, ctl6; - -- ads->ds_data = buf_addr; -- -- if (is_firstseg) { -- ads->ds_ctl1 |= seglen | (is_lastseg ? 0 : AR_TxMore); -- } else if (is_lastseg) { -- ads->ds_ctl0 = 0; -- ads->ds_ctl1 = seglen; -- ads->ds_ctl2 = AR5416DESC_CONST(ds0)->ds_ctl2; -- ads->ds_ctl3 = AR5416DESC_CONST(ds0)->ds_ctl3; -- } else { -- ads->ds_ctl0 = 0; -- ads->ds_ctl1 = seglen | AR_TxMore; -- ads->ds_ctl2 = 0; -- ads->ds_ctl3 = 0; -- } - ads->ds_txstatus0 = ads->ds_txstatus1 = 0; - ads->ds_txstatus2 = ads->ds_txstatus3 = 0; - ads->ds_txstatus4 = ads->ds_txstatus5 = 0; - ads->ds_txstatus6 = ads->ds_txstatus7 = 0; - ads->ds_txstatus8 = ads->ds_txstatus9 = 0; -+ -+ ACCESS_ONCE(ads->ds_link) = i->link; -+ ACCESS_ONCE(ads->ds_data) = i->buf_addr[0]; -+ -+ ctl1 = i->buf_len[0] | (i->is_last ? 0 : AR_TxMore); -+ ctl6 = SM(i->keytype, AR_EncrType); -+ -+ if (AR_SREV_9285(ah)) { -+ ads->ds_ctl8 = 0; -+ ads->ds_ctl9 = 0; -+ ads->ds_ctl10 = 0; -+ ads->ds_ctl11 = 0; -+ } -+ -+ if ((i->is_first || i->is_last) && -+ i->aggr != AGGR_BUF_MIDDLE && i->aggr != AGGR_BUF_LAST) { -+ ACCESS_ONCE(ads->ds_ctl2) = set11nTries(i->rates, 0) -+ | set11nTries(i->rates, 1) -+ | set11nTries(i->rates, 2) -+ | set11nTries(i->rates, 3) -+ | (i->dur_update ? AR_DurUpdateEna : 0) -+ | SM(0, AR_BurstDur); -+ -+ ACCESS_ONCE(ads->ds_ctl3) = set11nRate(i->rates, 0) -+ | set11nRate(i->rates, 1) -+ | set11nRate(i->rates, 2) -+ | set11nRate(i->rates, 3); -+ } else { -+ ACCESS_ONCE(ads->ds_ctl2) = 0; -+ ACCESS_ONCE(ads->ds_ctl3) = 0; -+ } -+ -+ if (!i->is_first) { -+ ACCESS_ONCE(ads->ds_ctl0) = 0; -+ ACCESS_ONCE(ads->ds_ctl1) = ctl1; -+ ACCESS_ONCE(ads->ds_ctl6) = ctl6; -+ return; -+ } -+ -+ ctl1 |= (i->keyix != ATH9K_TXKEYIX_INVALID ? SM(i->keyix, AR_DestIdx) : 0) -+ | SM(i->type, AR_FrameType) -+ | (i->flags & ATH9K_TXDESC_NOACK ? AR_NoAck : 0) -+ | (i->flags & ATH9K_TXDESC_EXT_ONLY ? AR_ExtOnly : 0) -+ | (i->flags & ATH9K_TXDESC_EXT_AND_CTL ? AR_ExtAndCtl : 0); -+ -+ switch (i->aggr) { -+ case AGGR_BUF_FIRST: -+ ctl6 |= SM(i->aggr_len, AR_AggrLen); -+ /* fall through */ -+ case AGGR_BUF_MIDDLE: -+ ctl1 |= AR_IsAggr | AR_MoreAggr; -+ ctl6 |= SM(i->ndelim, AR_PadDelim); -+ break; -+ case AGGR_BUF_LAST: -+ ctl1 |= AR_IsAggr; -+ break; -+ case AGGR_BUF_NONE: -+ break; -+ } -+ -+ ACCESS_ONCE(ads->ds_ctl0) = (i->pkt_len & AR_FrameLen) -+ | (i->flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0) -+ | SM(i->txpower, AR_XmitPower) -+ | (i->flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0) -+ | (i->flags & ATH9K_TXDESC_INTREQ ? AR_TxIntrReq : 0) -+ | (i->keyix != ATH9K_TXKEYIX_INVALID ? AR_DestIdxValid : 0) -+ | (i->flags & ATH9K_TXDESC_CLRDMASK ? AR_ClrDestMask : 0) -+ | (i->flags & ATH9K_TXDESC_RTSENA ? AR_RTSEnable : -+ (i->flags & ATH9K_TXDESC_CTSENA ? AR_CTSEnable : 0)); -+ -+ ACCESS_ONCE(ads->ds_ctl1) = ctl1; -+ ACCESS_ONCE(ads->ds_ctl6) = ctl6; -+ -+ if (i->aggr == AGGR_BUF_MIDDLE || i->aggr == AGGR_BUF_LAST) -+ return; -+ -+ ACCESS_ONCE(ads->ds_ctl4) = set11nPktDurRTSCTS(i->rates, 0) -+ | set11nPktDurRTSCTS(i->rates, 1); -+ -+ ACCESS_ONCE(ads->ds_ctl5) = set11nPktDurRTSCTS(i->rates, 2) -+ | set11nPktDurRTSCTS(i->rates, 3); -+ -+ ACCESS_ONCE(ads->ds_ctl7) = set11nRateFlags(i->rates, 0) -+ | set11nRateFlags(i->rates, 1) -+ | set11nRateFlags(i->rates, 2) -+ | set11nRateFlags(i->rates, 3) -+ | SM(i->rtscts_rate, AR_RTSCTSRate); - } - - static int ar9002_hw_proc_txdesc(struct ath_hw *ah, void *ds, -@@ -271,145 +342,6 @@ static int ar9002_hw_proc_txdesc(struct - return 0; - } - --static void ar9002_hw_set11n_txdesc(struct ath_hw *ah, void *ds, -- u32 pktLen, enum ath9k_pkt_type type, -- u32 txPower, u8 keyIx, -- enum ath9k_key_type keyType, u32 flags) --{ -- struct ar5416_desc *ads = AR5416DESC(ds); -- -- if (txPower > 63) -- txPower = 63; -- -- ads->ds_ctl0 = (pktLen & AR_FrameLen) -- | (flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0) -- | SM(txPower, AR_XmitPower) -- | (flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0) -- | (flags & ATH9K_TXDESC_INTREQ ? AR_TxIntrReq : 0) -- | (keyIx != ATH9K_TXKEYIX_INVALID ? AR_DestIdxValid : 0); -- -- ads->ds_ctl1 = -- (keyIx != ATH9K_TXKEYIX_INVALID ? SM(keyIx, AR_DestIdx) : 0) -- | SM(type, AR_FrameType) -- | (flags & ATH9K_TXDESC_NOACK ? AR_NoAck : 0) -- | (flags & ATH9K_TXDESC_EXT_ONLY ? AR_ExtOnly : 0) -- | (flags & ATH9K_TXDESC_EXT_AND_CTL ? AR_ExtAndCtl : 0); -- -- ads->ds_ctl6 = SM(keyType, AR_EncrType); -- -- if (AR_SREV_9285(ah) || AR_SREV_9271(ah)) { -- ads->ds_ctl8 = 0; -- ads->ds_ctl9 = 0; -- ads->ds_ctl10 = 0; -- ads->ds_ctl11 = 0; -- } --} -- --static void ar9002_hw_set_clrdmask(struct ath_hw *ah, void *ds, bool val) --{ -- struct ar5416_desc *ads = AR5416DESC(ds); -- -- if (val) -- ads->ds_ctl0 |= AR_ClrDestMask; -- else -- ads->ds_ctl0 &= ~AR_ClrDestMask; --} -- --static void ar9002_hw_set11n_ratescenario(struct ath_hw *ah, void *ds, -- void *lastds, -- u32 durUpdateEn, u32 rtsctsRate, -- u32 rtsctsDuration, -- struct ath9k_11n_rate_series series[], -- u32 nseries, u32 flags) --{ -- struct ar5416_desc *ads = AR5416DESC(ds); -- struct ar5416_desc *last_ads = AR5416DESC(lastds); -- u32 ds_ctl0; -- -- if (flags & (ATH9K_TXDESC_RTSENA | ATH9K_TXDESC_CTSENA)) { -- ds_ctl0 = ads->ds_ctl0; -- -- if (flags & ATH9K_TXDESC_RTSENA) { -- ds_ctl0 &= ~AR_CTSEnable; -- ds_ctl0 |= AR_RTSEnable; -- } else { -- ds_ctl0 &= ~AR_RTSEnable; -- ds_ctl0 |= AR_CTSEnable; -- } -- -- ads->ds_ctl0 = ds_ctl0; -- } else { -- ads->ds_ctl0 = -- (ads->ds_ctl0 & ~(AR_RTSEnable | AR_CTSEnable)); -- } -- -- ads->ds_ctl2 = set11nTries(series, 0) -- | set11nTries(series, 1) -- | set11nTries(series, 2) -- | set11nTries(series, 3) -- | (durUpdateEn ? AR_DurUpdateEna : 0) -- | SM(0, AR_BurstDur); -- -- ads->ds_ctl3 = set11nRate(series, 0) -- | set11nRate(series, 1) -- | set11nRate(series, 2) -- | set11nRate(series, 3); -- -- ads->ds_ctl4 = set11nPktDurRTSCTS(series, 0) -- | set11nPktDurRTSCTS(series, 1); -- -- ads->ds_ctl5 = set11nPktDurRTSCTS(series, 2) -- | set11nPktDurRTSCTS(series, 3); -- -- ads->ds_ctl7 = set11nRateFlags(series, 0) -- | set11nRateFlags(series, 1) -- | set11nRateFlags(series, 2) -- | set11nRateFlags(series, 3) -- | SM(rtsctsRate, AR_RTSCTSRate); -- last_ads->ds_ctl2 = ads->ds_ctl2; -- last_ads->ds_ctl3 = ads->ds_ctl3; --} -- --static void ar9002_hw_set11n_aggr_first(struct ath_hw *ah, void *ds, -- u32 aggrLen) --{ -- struct ar5416_desc *ads = AR5416DESC(ds); -- -- ads->ds_ctl1 |= (AR_IsAggr | AR_MoreAggr); -- ads->ds_ctl6 &= ~AR_AggrLen; -- ads->ds_ctl6 |= SM(aggrLen, AR_AggrLen); --} -- --static void ar9002_hw_set11n_aggr_middle(struct ath_hw *ah, void *ds, -- u32 numDelims) --{ -- struct ar5416_desc *ads = AR5416DESC(ds); -- unsigned int ctl6; -- -- ads->ds_ctl1 |= (AR_IsAggr | AR_MoreAggr); -- -- ctl6 = ads->ds_ctl6; -- ctl6 &= ~AR_PadDelim; -- ctl6 |= SM(numDelims, AR_PadDelim); -- ads->ds_ctl6 = ctl6; --} -- --static void ar9002_hw_set11n_aggr_last(struct ath_hw *ah, void *ds) --{ -- struct ar5416_desc *ads = AR5416DESC(ds); -- -- ads->ds_ctl1 |= AR_IsAggr; -- ads->ds_ctl1 &= ~AR_MoreAggr; -- ads->ds_ctl6 &= ~AR_PadDelim; --} -- --static void ar9002_hw_clr11n_aggr(struct ath_hw *ah, void *ds) --{ -- struct ar5416_desc *ads = AR5416DESC(ds); -- -- ads->ds_ctl1 &= (~AR_IsAggr & ~AR_MoreAggr); --} -- - void ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds, - u32 size, u32 flags) - { -@@ -433,13 +365,6 @@ void ar9002_hw_attach_mac_ops(struct ath - ops->rx_enable = ar9002_hw_rx_enable; - ops->set_desc_link = ar9002_hw_set_desc_link; - ops->get_isr = ar9002_hw_get_isr; -- ops->fill_txdesc = ar9002_hw_fill_txdesc; -+ ops->set_txdesc = ar9002_set_txdesc; - ops->proc_txdesc = ar9002_hw_proc_txdesc; -- ops->set11n_txdesc = ar9002_hw_set11n_txdesc; -- ops->set11n_ratescenario = ar9002_hw_set11n_ratescenario; -- ops->set11n_aggr_first = ar9002_hw_set11n_aggr_first; -- ops->set11n_aggr_middle = ar9002_hw_set11n_aggr_middle; -- ops->set11n_aggr_last = ar9002_hw_set11n_aggr_last; -- ops->clr11n_aggr = ar9002_hw_clr11n_aggr; -- ops->set_clrdmask = ar9002_hw_set_clrdmask; - } ---- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c -+++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c -@@ -652,8 +652,9 @@ static void ar9003_hw_detect_outlier(int - outlier_idx = max_idx; - else - outlier_idx = min_idx; -+ -+ mp_coeff[outlier_idx] = mp_avg; - } -- mp_coeff[outlier_idx] = mp_avg; - } - - static void ar9003_hw_tx_iqcal_load_avg_2_passes(struct ath_hw *ah, -@@ -884,6 +885,7 @@ static bool ar9003_hw_init_cal(struct at - if (txiqcal_done) - ar9003_hw_tx_iq_cal_post_proc(ah); - -+ ath9k_hw_loadnf(ah, chan); - ath9k_hw_start_nfcal(ah, true); - - /* Initialize list pointers */ ---- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c -+++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c -@@ -21,6 +21,132 @@ static void ar9003_hw_rx_enable(struct a - REG_WRITE(hw, AR_CR, 0); - } - -+static void -+ar9003_set_txdesc(struct ath_hw *ah, void *ds, struct ath_tx_info *i) -+{ -+ struct ar9003_txc *ads = ds; -+ int checksum = 0; -+ u32 val, ctl12, ctl17; -+ -+ val = (ATHEROS_VENDOR_ID << AR_DescId_S) | -+ (1 << AR_TxRxDesc_S) | -+ (1 << AR_CtrlStat_S) | -+ (i->qcu << AR_TxQcuNum_S) | 0x17; -+ -+ checksum += val; -+ ACCESS_ONCE(ads->info) = val; -+ -+ checksum += i->link; -+ ACCESS_ONCE(ads->link) = i->link; -+ -+ checksum += i->buf_addr[0]; -+ ACCESS_ONCE(ads->data0) = i->buf_addr[0]; -+ checksum += i->buf_addr[1]; -+ ACCESS_ONCE(ads->data1) = i->buf_addr[1]; -+ checksum += i->buf_addr[2]; -+ ACCESS_ONCE(ads->data2) = i->buf_addr[2]; -+ checksum += i->buf_addr[3]; -+ ACCESS_ONCE(ads->data3) = i->buf_addr[3]; -+ -+ checksum += (val = (i->buf_len[0] << AR_BufLen_S) & AR_BufLen); -+ ACCESS_ONCE(ads->ctl3) = val; -+ checksum += (val = (i->buf_len[1] << AR_BufLen_S) & AR_BufLen); -+ ACCESS_ONCE(ads->ctl5) = val; -+ checksum += (val = (i->buf_len[2] << AR_BufLen_S) & AR_BufLen); -+ ACCESS_ONCE(ads->ctl7) = val; -+ checksum += (val = (i->buf_len[3] << AR_BufLen_S) & AR_BufLen); -+ ACCESS_ONCE(ads->ctl9) = val; -+ -+ checksum = (u16) (((checksum & 0xffff) + (checksum >> 16)) & 0xffff); -+ ACCESS_ONCE(ads->ctl10) = checksum; -+ -+ if (i->is_first || i->is_last) { -+ ACCESS_ONCE(ads->ctl13) = set11nTries(i->rates, 0) -+ | set11nTries(i->rates, 1) -+ | set11nTries(i->rates, 2) -+ | set11nTries(i->rates, 3) -+ | (i->dur_update ? AR_DurUpdateEna : 0) -+ | SM(0, AR_BurstDur); -+ -+ ACCESS_ONCE(ads->ctl14) = set11nRate(i->rates, 0) -+ | set11nRate(i->rates, 1) -+ | set11nRate(i->rates, 2) -+ | set11nRate(i->rates, 3); -+ } else { -+ ACCESS_ONCE(ads->ctl13) = 0; -+ ACCESS_ONCE(ads->ctl14) = 0; -+ } -+ -+ ads->ctl20 = 0; -+ ads->ctl21 = 0; -+ ads->ctl22 = 0; -+ -+ ctl17 = SM(i->keytype, AR_EncrType); -+ if (!i->is_first) { -+ ACCESS_ONCE(ads->ctl11) = 0; -+ ACCESS_ONCE(ads->ctl12) = i->is_last ? 0 : AR_TxMore; -+ ACCESS_ONCE(ads->ctl15) = 0; -+ ACCESS_ONCE(ads->ctl16) = 0; -+ ACCESS_ONCE(ads->ctl17) = ctl17; -+ ACCESS_ONCE(ads->ctl18) = 0; -+ ACCESS_ONCE(ads->ctl19) = 0; -+ return; -+ } -+ -+ ACCESS_ONCE(ads->ctl11) = (i->pkt_len & AR_FrameLen) -+ | (i->flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0) -+ | SM(i->txpower, AR_XmitPower) -+ | (i->flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0) -+ | (i->keyix != ATH9K_TXKEYIX_INVALID ? AR_DestIdxValid : 0) -+ | (i->flags & ATH9K_TXDESC_LOWRXCHAIN ? AR_LowRxChain : 0) -+ | (i->flags & ATH9K_TXDESC_CLRDMASK ? AR_ClrDestMask : 0) -+ | (i->flags & ATH9K_TXDESC_RTSENA ? AR_RTSEnable : -+ (i->flags & ATH9K_TXDESC_CTSENA ? AR_CTSEnable : 0)); -+ -+ ctl12 = (i->keyix != ATH9K_TXKEYIX_INVALID ? -+ SM(i->keyix, AR_DestIdx) : 0) -+ | SM(i->type, AR_FrameType) -+ | (i->flags & ATH9K_TXDESC_NOACK ? AR_NoAck : 0) -+ | (i->flags & ATH9K_TXDESC_EXT_ONLY ? AR_ExtOnly : 0) -+ | (i->flags & ATH9K_TXDESC_EXT_AND_CTL ? AR_ExtAndCtl : 0); -+ -+ ctl17 |= (i->flags & ATH9K_TXDESC_LDPC ? AR_LDPC : 0); -+ switch (i->aggr) { -+ case AGGR_BUF_FIRST: -+ ctl17 |= SM(i->aggr_len, AR_AggrLen); -+ /* fall through */ -+ case AGGR_BUF_MIDDLE: -+ ctl12 |= AR_IsAggr | AR_MoreAggr; -+ ctl17 |= SM(i->ndelim, AR_PadDelim); -+ break; -+ case AGGR_BUF_LAST: -+ ctl12 |= AR_IsAggr; -+ break; -+ case AGGR_BUF_NONE: -+ break; -+ } -+ -+ val = (i->flags & ATH9K_TXDESC_PAPRD) >> ATH9K_TXDESC_PAPRD_S; -+ ctl12 |= SM(val, AR_PAPRDChainMask); -+ -+ ACCESS_ONCE(ads->ctl12) = ctl12; -+ ACCESS_ONCE(ads->ctl17) = ctl17; -+ -+ ACCESS_ONCE(ads->ctl15) = set11nPktDurRTSCTS(i->rates, 0) -+ | set11nPktDurRTSCTS(i->rates, 1); -+ -+ ACCESS_ONCE(ads->ctl16) = set11nPktDurRTSCTS(i->rates, 2) -+ | set11nPktDurRTSCTS(i->rates, 3); -+ -+ ACCESS_ONCE(ads->ctl18) = set11nRateFlags(i->rates, 0) -+ | set11nRateFlags(i->rates, 1) -+ | set11nRateFlags(i->rates, 2) -+ | set11nRateFlags(i->rates, 3) -+ | SM(i->rtscts_rate, AR_RTSCTSRate); -+ -+ ACCESS_ONCE(ads->ctl19) = AR_Not_Sounding; -+} -+ - static u16 ar9003_calc_ptr_chksum(struct ar9003_txc *ads) - { - int checksum; -@@ -185,47 +311,6 @@ static bool ar9003_hw_get_isr(struct ath - return true; - } - --static void ar9003_hw_fill_txdesc(struct ath_hw *ah, void *ds, u32 seglen, -- bool is_firstseg, bool is_lastseg, -- const void *ds0, dma_addr_t buf_addr, -- unsigned int qcu) --{ -- struct ar9003_txc *ads = (struct ar9003_txc *) ds; -- unsigned int descid = 0; -- -- ads->info = (ATHEROS_VENDOR_ID << AR_DescId_S) | -- (1 << AR_TxRxDesc_S) | -- (1 << AR_CtrlStat_S) | -- (qcu << AR_TxQcuNum_S) | 0x17; -- -- ads->data0 = buf_addr; -- ads->data1 = 0; -- ads->data2 = 0; -- ads->data3 = 0; -- -- ads->ctl3 = (seglen << AR_BufLen_S); -- ads->ctl3 &= AR_BufLen; -- -- /* Fill in pointer checksum and descriptor id */ -- ads->ctl10 = ar9003_calc_ptr_chksum(ads); -- ads->ctl10 |= (descid << AR_TxDescId_S); -- -- if (is_firstseg) { -- ads->ctl12 |= (is_lastseg ? 0 : AR_TxMore); -- } else if (is_lastseg) { -- ads->ctl11 = 0; -- ads->ctl12 = 0; -- ads->ctl13 = AR9003TXC_CONST(ds0)->ctl13; -- ads->ctl14 = AR9003TXC_CONST(ds0)->ctl14; -- } else { -- /* XXX Intermediate descriptor in a multi-descriptor frame.*/ -- ads->ctl11 = 0; -- ads->ctl12 = AR_TxMore; -- ads->ctl13 = 0; -- ads->ctl14 = 0; -- } --} -- - static int ar9003_hw_proc_txdesc(struct ath_hw *ah, void *ds, - struct ath_tx_status *ts) - { -@@ -310,161 +395,6 @@ static int ar9003_hw_proc_txdesc(struct - return 0; - } - --static void ar9003_hw_set11n_txdesc(struct ath_hw *ah, void *ds, -- u32 pktlen, enum ath9k_pkt_type type, u32 txpower, -- u8 keyIx, enum ath9k_key_type keyType, u32 flags) --{ -- struct ar9003_txc *ads = (struct ar9003_txc *) ds; -- -- if (txpower > ah->txpower_limit) -- txpower = ah->txpower_limit; -- -- if (txpower > 63) -- txpower = 63; -- -- ads->ctl11 = (pktlen & AR_FrameLen) -- | (flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0) -- | SM(txpower, AR_XmitPower) -- | (flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0) -- | (keyIx != ATH9K_TXKEYIX_INVALID ? AR_DestIdxValid : 0) -- | (flags & ATH9K_TXDESC_LOWRXCHAIN ? AR_LowRxChain : 0); -- -- ads->ctl12 = -- (keyIx != ATH9K_TXKEYIX_INVALID ? SM(keyIx, AR_DestIdx) : 0) -- | SM(type, AR_FrameType) -- | (flags & ATH9K_TXDESC_NOACK ? AR_NoAck : 0) -- | (flags & ATH9K_TXDESC_EXT_ONLY ? AR_ExtOnly : 0) -- | (flags & ATH9K_TXDESC_EXT_AND_CTL ? AR_ExtAndCtl : 0); -- -- ads->ctl17 = SM(keyType, AR_EncrType) | -- (flags & ATH9K_TXDESC_LDPC ? AR_LDPC : 0); -- ads->ctl18 = 0; -- ads->ctl19 = AR_Not_Sounding; -- -- ads->ctl20 = 0; -- ads->ctl21 = 0; -- ads->ctl22 = 0; --} -- --static void ar9003_hw_set_clrdmask(struct ath_hw *ah, void *ds, bool val) --{ -- struct ar9003_txc *ads = (struct ar9003_txc *) ds; -- -- if (val) -- ads->ctl11 |= AR_ClrDestMask; -- else -- ads->ctl11 &= ~AR_ClrDestMask; --} -- --static void ar9003_hw_set11n_ratescenario(struct ath_hw *ah, void *ds, -- void *lastds, -- u32 durUpdateEn, u32 rtsctsRate, -- u32 rtsctsDuration, -- struct ath9k_11n_rate_series series[], -- u32 nseries, u32 flags) --{ -- struct ar9003_txc *ads = (struct ar9003_txc *) ds; -- struct ar9003_txc *last_ads = (struct ar9003_txc *) lastds; -- u_int32_t ctl11; -- -- if (flags & (ATH9K_TXDESC_RTSENA | ATH9K_TXDESC_CTSENA)) { -- ctl11 = ads->ctl11; -- -- if (flags & ATH9K_TXDESC_RTSENA) { -- ctl11 &= ~AR_CTSEnable; -- ctl11 |= AR_RTSEnable; -- } else { -- ctl11 &= ~AR_RTSEnable; -- ctl11 |= AR_CTSEnable; -- } -- -- ads->ctl11 = ctl11; -- } else { -- ads->ctl11 = (ads->ctl11 & ~(AR_RTSEnable | AR_CTSEnable)); -- } -- -- ads->ctl13 = set11nTries(series, 0) -- | set11nTries(series, 1) -- | set11nTries(series, 2) -- | set11nTries(series, 3) -- | (durUpdateEn ? AR_DurUpdateEna : 0) -- | SM(0, AR_BurstDur); -- -- ads->ctl14 = set11nRate(series, 0) -- | set11nRate(series, 1) -- | set11nRate(series, 2) -- | set11nRate(series, 3); -- -- ads->ctl15 = set11nPktDurRTSCTS(series, 0) -- | set11nPktDurRTSCTS(series, 1); -- -- ads->ctl16 = set11nPktDurRTSCTS(series, 2) -- | set11nPktDurRTSCTS(series, 3); -- -- ads->ctl18 = set11nRateFlags(series, 0) -- | set11nRateFlags(series, 1) -- | set11nRateFlags(series, 2) -- | set11nRateFlags(series, 3) -- | SM(rtsctsRate, AR_RTSCTSRate); -- ads->ctl19 = AR_Not_Sounding; -- -- last_ads->ctl13 = ads->ctl13; -- last_ads->ctl14 = ads->ctl14; --} -- --static void ar9003_hw_set11n_aggr_first(struct ath_hw *ah, void *ds, -- u32 aggrLen) --{ -- struct ar9003_txc *ads = (struct ar9003_txc *) ds; -- -- ads->ctl12 |= (AR_IsAggr | AR_MoreAggr); -- -- ads->ctl17 &= ~AR_AggrLen; -- ads->ctl17 |= SM(aggrLen, AR_AggrLen); --} -- --static void ar9003_hw_set11n_aggr_middle(struct ath_hw *ah, void *ds, -- u32 numDelims) --{ -- struct ar9003_txc *ads = (struct ar9003_txc *) ds; -- unsigned int ctl17; -- -- ads->ctl12 |= (AR_IsAggr | AR_MoreAggr); -- -- /* -- * We use a stack variable to manipulate ctl6 to reduce uncached -- * read modify, modfiy, write. -- */ -- ctl17 = ads->ctl17; -- ctl17 &= ~AR_PadDelim; -- ctl17 |= SM(numDelims, AR_PadDelim); -- ads->ctl17 = ctl17; --} -- --static void ar9003_hw_set11n_aggr_last(struct ath_hw *ah, void *ds) --{ -- struct ar9003_txc *ads = (struct ar9003_txc *) ds; -- -- ads->ctl12 |= AR_IsAggr; -- ads->ctl12 &= ~AR_MoreAggr; -- ads->ctl17 &= ~AR_PadDelim; --} -- --static void ar9003_hw_clr11n_aggr(struct ath_hw *ah, void *ds) --{ -- struct ar9003_txc *ads = (struct ar9003_txc *) ds; -- -- ads->ctl12 &= (~AR_IsAggr & ~AR_MoreAggr); --} -- --void ar9003_hw_set_paprd_txdesc(struct ath_hw *ah, void *ds, u8 chains) --{ -- struct ar9003_txc *ads = ds; -- -- ads->ctl12 |= SM(chains, AR_PAPRDChainMask); --} --EXPORT_SYMBOL(ar9003_hw_set_paprd_txdesc); -- - void ar9003_hw_attach_mac_ops(struct ath_hw *hw) - { - struct ath_hw_ops *ops = ath9k_hw_ops(hw); -@@ -472,15 +402,8 @@ void ar9003_hw_attach_mac_ops(struct ath - ops->rx_enable = ar9003_hw_rx_enable; - ops->set_desc_link = ar9003_hw_set_desc_link; - ops->get_isr = ar9003_hw_get_isr; -- ops->fill_txdesc = ar9003_hw_fill_txdesc; -+ ops->set_txdesc = ar9003_set_txdesc; - ops->proc_txdesc = ar9003_hw_proc_txdesc; -- ops->set11n_txdesc = ar9003_hw_set11n_txdesc; -- ops->set11n_ratescenario = ar9003_hw_set11n_ratescenario; -- ops->set11n_aggr_first = ar9003_hw_set11n_aggr_first; -- ops->set11n_aggr_middle = ar9003_hw_set11n_aggr_middle; -- ops->set11n_aggr_last = ar9003_hw_set11n_aggr_last; -- ops->clr11n_aggr = ar9003_hw_clr11n_aggr; -- ops->set_clrdmask = ar9003_hw_set_clrdmask; - } - - void ath9k_hw_set_rx_bufsize(struct ath_hw *ah, u16 buf_size) ---- a/drivers/net/wireless/ath/ath9k/ath9k.h -+++ b/drivers/net/wireless/ath/ath9k/ath9k.h -@@ -87,17 +87,14 @@ struct ath_config { - * @BUF_AMPDU: This buffer is an ampdu, as part of an aggregate (during TX) - * @BUF_AGGR: Indicates whether the buffer can be aggregated - * (used in aggregation scheduling) -- * @BUF_XRETRY: To denote excessive retries of the buffer - */ - enum buffer_type { - BUF_AMPDU = BIT(0), - BUF_AGGR = BIT(1), -- BUF_XRETRY = BIT(2), - }; - - #define bf_isampdu(bf) (bf->bf_state.bf_type & BUF_AMPDU) - #define bf_isaggr(bf) (bf->bf_state.bf_type & BUF_AGGR) --#define bf_isxretried(bf) (bf->bf_state.bf_type & BUF_XRETRY) - - #define ATH_TXSTATUS_RING_SIZE 64 - -@@ -216,6 +213,7 @@ struct ath_frame_info { - struct ath_buf_state { - u8 bf_type; - u8 bfs_paprd; -+ u8 ndelim; - u16 seqno; - unsigned long bfs_paprd_timestamp; - }; -@@ -230,7 +228,6 @@ struct ath_buf { - dma_addr_t bf_daddr; /* physical addr of desc */ - dma_addr_t bf_buf_addr; /* physical addr of data buffer, for DMA */ - bool bf_stale; -- u16 bf_flags; - struct ath_buf_state bf_state; - }; - -@@ -277,8 +274,7 @@ struct ath_tx_control { - }; - - #define ATH_TX_ERROR 0x01 --#define ATH_TX_XRETRY 0x02 --#define ATH_TX_BAR 0x04 -+#define ATH_TX_BAR 0x02 - - /** - * @txq_map: Index is mac80211 queue number. This is ---- a/drivers/net/wireless/ath/ath9k/beacon.c -+++ b/drivers/net/wireless/ath/ath9k/beacon.c -@@ -73,44 +73,39 @@ static void ath_beacon_setup(struct ath_ - struct sk_buff *skb = bf->bf_mpdu; - struct ath_hw *ah = sc->sc_ah; - struct ath_common *common = ath9k_hw_common(ah); -- struct ath_desc *ds; -- struct ath9k_11n_rate_series series[4]; -- int flags, ctsrate = 0, ctsduration = 0; -+ struct ath_tx_info info; - struct ieee80211_supported_band *sband; -+ u8 chainmask = ah->txchainmask; - u8 rate = 0; - - ath9k_reset_beacon_status(sc); - -- ds = bf->bf_desc; -- flags = ATH9K_TXDESC_NOACK; -- -- ds->ds_link = 0; -- - sband = &sc->sbands[common->hw->conf.channel->band]; - rate = sband->bitrates[rateidx].hw_value; - if (sc->sc_flags & SC_OP_PREAMBLE_SHORT) - rate |= sband->bitrates[rateidx].hw_value_short; - -- ath9k_hw_set11n_txdesc(ah, ds, skb->len + FCS_LEN, -- ATH9K_PKT_TYPE_BEACON, -- MAX_RATE_POWER, -- ATH9K_TXKEYIX_INVALID, -- ATH9K_KEY_TYPE_CLEAR, -- flags); -- -- /* NB: beacon's BufLen must be a multiple of 4 bytes */ -- ath9k_hw_filltxdesc(ah, ds, roundup(skb->len, 4), -- true, true, ds, bf->bf_buf_addr, -- sc->beacon.beaconq); -- -- memset(series, 0, sizeof(struct ath9k_11n_rate_series) * 4); -- series[0].Tries = 1; -- series[0].Rate = rate; -- series[0].ChSel = ath_txchainmask_reduction(sc, -- ah->txchainmask, series[0].Rate); -- series[0].RateFlags = (ctsrate) ? ATH9K_RATESERIES_RTS_CTS : 0; -- ath9k_hw_set11n_ratescenario(ah, ds, ds, 0, ctsrate, ctsduration, -- series, 4, 0); -+ memset(&info, 0, sizeof(info)); -+ info.pkt_len = skb->len + FCS_LEN; -+ info.type = ATH9K_PKT_TYPE_BEACON; -+ info.txpower = MAX_RATE_POWER; -+ info.keyix = ATH9K_TXKEYIX_INVALID; -+ info.keytype = ATH9K_KEY_TYPE_CLEAR; -+ info.flags = ATH9K_TXDESC_NOACK; -+ -+ info.buf_addr[0] = bf->bf_buf_addr; -+ info.buf_len[0] = roundup(skb->len, 4); -+ -+ info.is_first = true; -+ info.is_last = true; -+ -+ info.qcu = sc->beacon.beaconq; -+ -+ info.rates[0].Tries = 1; -+ info.rates[0].Rate = rate; -+ info.rates[0].ChSel = ath_txchainmask_reduction(sc, chainmask, rate); -+ -+ ath9k_hw_set_txdesc(ah, bf->bf_desc, &info); - } - - static void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb) -@@ -517,6 +512,7 @@ static void ath_beacon_config_ap(struct - /* Set the computed AP beacon timers */ - - ath9k_hw_disable_interrupts(ah); -+ sc->sc_flags |= SC_OP_TSF_RESET; - ath9k_beacon_init(sc, nexttbtt, intval); - sc->beacon.bmisscnt = 0; - ath9k_hw_set_interrupts(ah, ah->imask); ---- a/drivers/net/wireless/ath/ath9k/debug.c -+++ b/drivers/net/wireless/ath/ath9k/debug.c -@@ -826,7 +826,8 @@ static ssize_t read_file_misc(struct fil - } - - void ath_debug_stat_tx(struct ath_softc *sc, struct ath_buf *bf, -- struct ath_tx_status *ts, struct ath_txq *txq) -+ struct ath_tx_status *ts, struct ath_txq *txq, -+ unsigned int flags) - { - #define TX_SAMP_DBG(c) (sc->debug.bb_mac_samp[sc->debug.sampidx].ts\ - [sc->debug.tsidx].c) -@@ -836,12 +837,12 @@ 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 (bf_isxretried(bf)) -+ if (flags & ATH_TX_BAR) - TX_STAT_INC(qnum, a_xretries); - else - TX_STAT_INC(qnum, a_completed); - } else { -- if (bf_isxretried(bf)) -+ if (ts->ts_status & ATH9K_TXERR_XRETRY) - TX_STAT_INC(qnum, xretries); - else - TX_STAT_INC(qnum, completed); ---- a/drivers/net/wireless/ath/ath9k/debug.h -+++ b/drivers/net/wireless/ath/ath9k/debug.h -@@ -230,7 +230,8 @@ int ath9k_init_debug(struct ath_hw *ah); - void ath9k_debug_samp_bb_mac(struct ath_softc *sc); - void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status); - void ath_debug_stat_tx(struct ath_softc *sc, struct ath_buf *bf, -- struct ath_tx_status *ts, struct ath_txq *txq); -+ struct ath_tx_status *ts, struct ath_txq *txq, -+ unsigned int flags); - void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs); - - #else -@@ -252,7 +253,8 @@ static inline void ath_debug_stat_interr - static inline void ath_debug_stat_tx(struct ath_softc *sc, - struct ath_buf *bf, - struct ath_tx_status *ts, -- struct ath_txq *txq) -+ struct ath_txq *txq, -+ unsigned int flags) - { - } - ---- a/drivers/net/wireless/ath/ath9k/hw-ops.h -+++ b/drivers/net/wireless/ath/ath9k/hw-ops.h -@@ -54,13 +54,10 @@ static inline bool ath9k_hw_getisr(struc - return ath9k_hw_ops(ah)->get_isr(ah, masked); - } - --static inline void ath9k_hw_filltxdesc(struct ath_hw *ah, void *ds, u32 seglen, -- bool is_firstseg, bool is_lastseg, -- const void *ds0, dma_addr_t buf_addr, -- unsigned int qcu) -+static inline void ath9k_hw_set_txdesc(struct ath_hw *ah, void *ds, -+ struct ath_tx_info *i) - { -- ath9k_hw_ops(ah)->fill_txdesc(ah, ds, seglen, is_firstseg, is_lastseg, -- ds0, buf_addr, qcu); -+ return ath9k_hw_ops(ah)->set_txdesc(ah, ds, i); - } - - static inline int ath9k_hw_txprocdesc(struct ath_hw *ah, void *ds, -@@ -69,55 +66,6 @@ static inline int ath9k_hw_txprocdesc(st - return ath9k_hw_ops(ah)->proc_txdesc(ah, ds, ts); - } - --static inline void ath9k_hw_set11n_txdesc(struct ath_hw *ah, void *ds, -- u32 pktLen, enum ath9k_pkt_type type, -- u32 txPower, u32 keyIx, -- enum ath9k_key_type keyType, -- u32 flags) --{ -- ath9k_hw_ops(ah)->set11n_txdesc(ah, ds, pktLen, type, txPower, keyIx, -- keyType, flags); --} -- --static inline void ath9k_hw_set11n_ratescenario(struct ath_hw *ah, void *ds, -- void *lastds, -- u32 durUpdateEn, u32 rtsctsRate, -- u32 rtsctsDuration, -- struct ath9k_11n_rate_series series[], -- u32 nseries, u32 flags) --{ -- ath9k_hw_ops(ah)->set11n_ratescenario(ah, ds, lastds, durUpdateEn, -- rtsctsRate, rtsctsDuration, series, -- nseries, flags); --} -- --static inline void ath9k_hw_set11n_aggr_first(struct ath_hw *ah, void *ds, -- u32 aggrLen) --{ -- ath9k_hw_ops(ah)->set11n_aggr_first(ah, ds, aggrLen); --} -- --static inline void ath9k_hw_set11n_aggr_middle(struct ath_hw *ah, void *ds, -- u32 numDelims) --{ -- ath9k_hw_ops(ah)->set11n_aggr_middle(ah, ds, numDelims); --} -- --static inline void ath9k_hw_set11n_aggr_last(struct ath_hw *ah, void *ds) --{ -- ath9k_hw_ops(ah)->set11n_aggr_last(ah, ds); --} -- --static inline void ath9k_hw_clr11n_aggr(struct ath_hw *ah, void *ds) --{ -- ath9k_hw_ops(ah)->clr11n_aggr(ah, ds); --} -- --static inline void ath9k_hw_set_clrdmask(struct ath_hw *ah, void *ds, bool val) --{ -- ath9k_hw_ops(ah)->set_clrdmask(ah, ds, val); --} -- - static inline void ath9k_hw_antdiv_comb_conf_get(struct ath_hw *ah, - struct ath_hw_antcomb_conf *antconf) - { -@@ -233,11 +181,6 @@ static inline void ath9k_hw_restore_chai - return ath9k_hw_private_ops(ah)->restore_chainmask(ah); - } - --static inline void ath9k_hw_set_diversity(struct ath_hw *ah, bool value) --{ -- return ath9k_hw_private_ops(ah)->set_diversity(ah, value); --} -- - static inline bool ath9k_hw_ani_control(struct ath_hw *ah, - enum ath9k_ani_cmd cmd, int param) - { ---- a/drivers/net/wireless/ath/ath9k/hw.c -+++ b/drivers/net/wireless/ath/ath9k/hw.c -@@ -1496,14 +1496,16 @@ int ath9k_hw_reset(struct ath_hw *ah, st - } - ah->noise = ath9k_hw_getchan_noise(ah, chan); - -+ if ((AR_SREV_9280(ah) && common->bus_ops->ath_bus_type == ATH_PCI) || -+ (AR_SREV_9300_20_OR_LATER(ah) && IS_CHAN_5GHZ(chan))) -+ bChannelChange = false; -+ - if (bChannelChange && - (ah->chip_fullsleep != true) && - (ah->curchan != NULL) && - (chan->channel != ah->curchan->channel) && - ((chan->channelFlags & CHANNEL_ALL) == -- (ah->curchan->channelFlags & CHANNEL_ALL)) && -- (!AR_SREV_9280(ah) || AR_DEVID_7010(ah))) { -- -+ (ah->curchan->channelFlags & CHANNEL_ALL))) { - if (ath9k_hw_channel_change(ah, chan)) { - ath9k_hw_loadnf(ah, ah->curchan); - ath9k_hw_start_nfcal(ah, true); ---- a/drivers/net/wireless/ath/ath9k/hw.h -+++ b/drivers/net/wireless/ath/ath9k/hw.h -@@ -583,7 +583,6 @@ struct ath_hw_private_ops { - bool (*rfbus_req)(struct ath_hw *ah); - void (*rfbus_done)(struct ath_hw *ah); - void (*restore_chainmask)(struct ath_hw *ah); -- void (*set_diversity)(struct ath_hw *ah, bool value); - u32 (*compute_pll_control)(struct ath_hw *ah, - struct ath9k_channel *chan); - bool (*ani_control)(struct ath_hw *ah, enum ath9k_ani_cmd cmd, -@@ -615,30 +614,10 @@ struct ath_hw_ops { - u8 rxchainmask, - bool longcal); - bool (*get_isr)(struct ath_hw *ah, enum ath9k_int *masked); -- void (*fill_txdesc)(struct ath_hw *ah, void *ds, u32 seglen, -- bool is_firstseg, bool is_is_lastseg, -- const void *ds0, dma_addr_t buf_addr, -- unsigned int qcu); -+ void (*set_txdesc)(struct ath_hw *ah, void *ds, -+ struct ath_tx_info *i); - int (*proc_txdesc)(struct ath_hw *ah, void *ds, - struct ath_tx_status *ts); -- void (*set11n_txdesc)(struct ath_hw *ah, void *ds, -- u32 pktLen, enum ath9k_pkt_type type, -- u32 txPower, u8 keyIx, -- enum ath9k_key_type keyType, -- u32 flags); -- void (*set11n_ratescenario)(struct ath_hw *ah, void *ds, -- void *lastds, -- u32 durUpdateEn, u32 rtsctsRate, -- u32 rtsctsDuration, -- struct ath9k_11n_rate_series series[], -- u32 nseries, u32 flags); -- void (*set11n_aggr_first)(struct ath_hw *ah, void *ds, -- u32 aggrLen); -- void (*set11n_aggr_middle)(struct ath_hw *ah, void *ds, -- u32 numDelims); -- void (*set11n_aggr_last)(struct ath_hw *ah, void *ds); -- void (*clr11n_aggr)(struct ath_hw *ah, void *ds); -- void (*set_clrdmask)(struct ath_hw *ah, void *ds, bool val); - void (*antdiv_comb_conf_get)(struct ath_hw *ah, - struct ath_hw_antcomb_conf *antconf); - void (*antdiv_comb_conf_set)(struct ath_hw *ah, ---- a/drivers/net/wireless/ath/ath9k/mac.c -+++ b/drivers/net/wireless/ath/ath9k/mac.c -@@ -62,18 +62,6 @@ void ath9k_hw_txstart(struct ath_hw *ah, - } - EXPORT_SYMBOL(ath9k_hw_txstart); - --void ath9k_hw_cleartxdesc(struct ath_hw *ah, void *ds) --{ -- struct ar5416_desc *ads = AR5416DESC(ds); -- -- ads->ds_txstatus0 = ads->ds_txstatus1 = 0; -- ads->ds_txstatus2 = ads->ds_txstatus3 = 0; -- ads->ds_txstatus4 = ads->ds_txstatus5 = 0; -- ads->ds_txstatus6 = ads->ds_txstatus7 = 0; -- ads->ds_txstatus8 = ads->ds_txstatus9 = 0; --} --EXPORT_SYMBOL(ath9k_hw_cleartxdesc); -- - u32 ath9k_hw_numtxpending(struct ath_hw *ah, u32 q) - { - u32 npend; -@@ -596,7 +584,7 @@ int ath9k_hw_rxprocdesc(struct ath_hw *a - else - rs->rs_keyix = ATH9K_RXKEYIX_INVALID; - -- rs->rs_rate = RXSTATUS_RATE(ah, (&ads)); -+ rs->rs_rate = MS(ads.ds_rxstatus0, AR_RxRate); - rs->rs_more = (ads.ds_rxstatus1 & AR_RxMore) ? 1 : 0; - - rs->rs_isaggr = (ads.ds_rxstatus8 & AR_RxAggr) ? 1 : 0; ---- a/drivers/net/wireless/ath/ath9k/mac.h -+++ b/drivers/net/wireless/ath/ath9k/mac.h -@@ -17,10 +17,6 @@ - #ifndef MAC_H - #define MAC_H - --#define RXSTATUS_RATE(ah, ads) (AR_SREV_5416_20_OR_LATER(ah) ? \ -- MS(ads->ds_rxstatus0, AR_RxRate) : \ -- (ads->ds_rxstatus3 >> 2) & 0xFF) -- - #define set11nTries(_series, _index) \ - (SM((_series)[_index].Tries, AR_XmitDataTries##_index)) - -@@ -263,7 +259,11 @@ struct ath_desc { - #define ATH9K_TXDESC_VMF 0x0100 - #define ATH9K_TXDESC_FRAG_IS_ON 0x0200 - #define ATH9K_TXDESC_LOWRXCHAIN 0x0400 --#define ATH9K_TXDESC_LDPC 0x00010000 -+#define ATH9K_TXDESC_LDPC 0x0800 -+#define ATH9K_TXDESC_CLRDMASK 0x1000 -+ -+#define ATH9K_TXDESC_PAPRD 0x70000 -+#define ATH9K_TXDESC_PAPRD_S 16 - - #define ATH9K_RXDESC_INTREQ 0x0020 - -@@ -659,6 +659,13 @@ struct ath9k_11n_rate_series { - u32 RateFlags; - }; - -+enum aggr_type { -+ AGGR_BUF_NONE, -+ AGGR_BUF_FIRST, -+ AGGR_BUF_MIDDLE, -+ AGGR_BUF_LAST, -+}; -+ - enum ath9k_key_type { - ATH9K_KEY_TYPE_CLEAR, - ATH9K_KEY_TYPE_WEP, -@@ -666,6 +673,33 @@ enum ath9k_key_type { - ATH9K_KEY_TYPE_TKIP, - }; - -+struct ath_tx_info { -+ u8 qcu; -+ -+ bool is_first; -+ bool is_last; -+ -+ enum aggr_type aggr; -+ u8 ndelim; -+ u16 aggr_len; -+ -+ dma_addr_t link; -+ int pkt_len; -+ u32 flags; -+ -+ dma_addr_t buf_addr[4]; -+ int buf_len[4]; -+ -+ struct ath9k_11n_rate_series rates[4]; -+ u8 rtscts_rate; -+ bool dur_update; -+ -+ enum ath9k_pkt_type type; -+ enum ath9k_key_type keytype; -+ u8 keyix; -+ u8 txpower; -+}; -+ - struct ath_hw; - struct ath9k_channel; - enum ath9k_int; -@@ -673,7 +707,6 @@ enum ath9k_int; - u32 ath9k_hw_gettxbuf(struct ath_hw *ah, u32 q); - void ath9k_hw_puttxbuf(struct ath_hw *ah, u32 q, u32 txdp); - void ath9k_hw_txstart(struct ath_hw *ah, u32 q); --void ath9k_hw_cleartxdesc(struct ath_hw *ah, void *ds); - u32 ath9k_hw_numtxpending(struct ath_hw *ah, u32 q); - bool ath9k_hw_updatetxtriglevel(struct ath_hw *ah, bool bIncTrigLevel); - bool ath9k_hw_stop_dma_queue(struct ath_hw *ah, u32 q); --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c -@@ -111,24 +111,29 @@ void ath9k_ps_wakeup(struct ath_softc *s - void ath9k_ps_restore(struct ath_softc *sc) - { - struct ath_common *common = ath9k_hw_common(sc->sc_ah); -+ enum ath9k_power_mode mode; - unsigned long flags; - - spin_lock_irqsave(&sc->sc_pm_lock, flags); +@@ -118,7 +118,7 @@ void ath9k_ps_restore(struct ath_softc * if (--sc->ps_usecount != 0) goto unlock; -- spin_lock(&common->cc_lock); -- ath_hw_cycle_counters_update(common); -- spin_unlock(&common->cc_lock); -- - if (sc->ps_idle) -- ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_FULL_SLEEP); -+ mode = ATH9K_PM_FULL_SLEEP; +- if (sc->ps_idle) ++ if (sc->ps_idle && (sc->ps_flags & PS_WAIT_FOR_TX_ACK)) + mode = ATH9K_PM_FULL_SLEEP; else if (sc->ps_enabled && - !(sc->ps_flags & (PS_WAIT_FOR_BEACON | - PS_WAIT_FOR_CAB | - PS_WAIT_FOR_PSPOLL_DATA | - PS_WAIT_FOR_TX_ACK))) -- ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_NETWORK_SLEEP); -+ mode = ATH9K_PM_NETWORK_SLEEP; -+ else -+ goto unlock; -+ -+ spin_lock(&common->cc_lock); -+ ath_hw_cycle_counters_update(common); -+ spin_unlock(&common->cc_lock); -+ -+ ath9k_hw_setpower(sc->sc_ah, mode); - - unlock: - spin_unlock_irqrestore(&sc->sc_pm_lock, flags); -@@ -247,8 +252,8 @@ static bool ath_prepare_reset(struct ath - - if (!flush) { - if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) -- ath_rx_tasklet(sc, 0, true); -- ath_rx_tasklet(sc, 0, false); -+ ath_rx_tasklet(sc, 1, true); -+ ath_rx_tasklet(sc, 1, false); - } else { - ath_flushrecv(sc); - } -@@ -669,15 +674,15 @@ void ath9k_tasklet(unsigned long data) - u32 status = sc->intrstatus; - u32 rxmask; - -+ ath9k_ps_wakeup(sc); -+ spin_lock(&sc->sc_pcu_lock); -+ - if ((status & ATH9K_INT_FATAL) || - (status & ATH9K_INT_BB_WATCHDOG)) { - ieee80211_queue_work(sc->hw, &sc->hw_reset_work); -- return; -+ goto out; - } - -- ath9k_ps_wakeup(sc); -- spin_lock(&sc->sc_pcu_lock); -- - /* - * Only run the baseband hang check if beacons stop working in AP or - * IBSS mode, because it has a high false positive rate. For station -@@ -725,6 +730,7 @@ void ath9k_tasklet(unsigned long data) - if (status & ATH9K_INT_GENTIMER) - ath_gen_timer_isr(sc->sc_ah); - -+out: - /* re-enable hardware interrupt */ - ath9k_hw_enable_interrupts(ah); - -@@ -2015,6 +2021,7 @@ static void ath9k_config_bss(struct ath_ - /* Stop ANI */ - sc->sc_flags &= ~SC_OP_ANI_RUN; - del_timer_sync(&common->ani.timer); -+ memset(&sc->caldata, 0, sizeof(sc->caldata)); - } - } - ---- a/drivers/net/wireless/ath/ath9k/pci.c -+++ b/drivers/net/wireless/ath/ath9k/pci.c -@@ -332,16 +332,16 @@ static int ath_pci_resume(struct device - if ((val & 0x0000ff00) != 0) - pci_write_config_dword(pdev, 0x40, val & 0xffff00ff); - -+ ath9k_ps_wakeup(sc); - /* Enable LED */ - ath9k_hw_cfg_output(sc->sc_ah, sc->sc_ah->led_pin, - AR_GPIO_OUTPUT_MUX_AS_OUTPUT); -- ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 1); -+ ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 0); - - /* - * Reset key cache to sane defaults (all entries cleared) instead of - * semi-random values after suspend/resume. - */ -- ath9k_ps_wakeup(sc); - ath9k_cmn_init_crypto(sc->sc_ah); - ath9k_ps_restore(sc); - ---- a/drivers/net/wireless/ath/ath9k/recv.c -+++ b/drivers/net/wireless/ath/ath9k/recv.c -@@ -1839,7 +1839,7 @@ int ath_rx_tasklet(struct ath_softc *sc, - * If we're asked to flush receive queue, directly - * chain it back at the queue without processing it. - */ -- if (flush) -+ if (sc->sc_flags & SC_OP_RXFLUSH) - goto requeue_drop_frag; - - retval = ath9k_rx_skb_preprocess(common, hw, hdr, &rs, -@@ -1967,7 +1967,8 @@ requeue: - } else { - list_move_tail(&bf->list, &sc->rx.rxbuf); - ath_rx_buf_link(sc, bf); -- ath9k_hw_rxena(ah); -+ if (!flush) -+ ath9k_hw_rxena(ah); - } - } while (1); - ---- a/drivers/net/wireless/ath/ath9k/xmit.c -+++ b/drivers/net/wireless/ath/ath9k/xmit.c -@@ -56,10 +56,9 @@ static void ath_tx_complete_buf(struct a - struct ath_tx_status *ts, int txok, int sendbar); - static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq, - struct list_head *head, bool internal); --static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, int len); - static void ath_tx_rc_status(struct ath_softc *sc, struct ath_buf *bf, - struct ath_tx_status *ts, int nframes, int nbad, -- int txok, bool update_rc); -+ int txok); - static void ath_tx_update_baw(struct ath_softc *sc, struct ath_atx_tid *tid, - int seqno); - static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc, -@@ -263,6 +262,7 @@ static void ath_tx_set_retry(struct ath_ - struct sk_buff *skb) - { - struct ath_frame_info *fi = get_frame_info(skb); -+ struct ath_buf *bf = fi->bf; - struct ieee80211_hdr *hdr; - - TX_STAT_INC(txq->axq_qnum, a_retries); -@@ -271,6 +271,8 @@ static void ath_tx_set_retry(struct ath_ - - hdr = (struct ieee80211_hdr *)skb->data; - hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_RETRY); -+ dma_sync_single_for_device(sc->dev, bf->bf_buf_addr, -+ sizeof(*hdr), DMA_TO_DEVICE); - } - - static struct ath_buf *ath_tx_get_buffer(struct ath_softc *sc) -@@ -390,11 +392,9 @@ static void ath_tx_complete_aggr(struct - while (bf) { - bf_next = bf->bf_next; - -- bf->bf_state.bf_type |= BUF_XRETRY; - if (!bf->bf_stale || bf_next != NULL) - list_move_tail(&bf->list, &bf_head); - -- ath_tx_rc_status(sc, bf, ts, 1, 1, 0, false); - ath_tx_complete_buf(sc, bf, txq, &bf_head, ts, - 0, 0); - -@@ -470,7 +470,6 @@ static void ath_tx_complete_aggr(struct - clear_filter = true; - txpending = 1; - } else { -- bf->bf_state.bf_type |= BUF_XRETRY; - txfail = 1; - sendbar = 1; - txfail_cnt++; -@@ -497,17 +496,14 @@ static void ath_tx_complete_aggr(struct - - if (rc_update && (acked_cnt == 1 || txfail_cnt == 1)) { - memcpy(tx_info->control.rates, rates, sizeof(rates)); -- ath_tx_rc_status(sc, bf, ts, nframes, nbad, txok, true); -+ ath_tx_rc_status(sc, bf, ts, nframes, nbad, txok); - rc_update = false; -- } else { -- ath_tx_rc_status(sc, bf, ts, nframes, nbad, txok, false); - } - - ath_tx_complete_buf(sc, bf, txq, &bf_head, ts, - !txfail, sendbar); - } else { - /* retry the un-acked ones */ -- ath9k_hw_set_clrdmask(sc->sc_ah, bf->bf_desc, false); - if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)) { - if (bf->bf_next == NULL && bf_last->bf_stale) { - struct ath_buf *tbf; -@@ -523,26 +519,13 @@ static void ath_tx_complete_aggr(struct - ath_tx_update_baw(sc, tid, seqno); - spin_unlock_bh(&txq->axq_lock); - -- bf->bf_state.bf_type |= -- BUF_XRETRY; -- ath_tx_rc_status(sc, bf, ts, nframes, -- nbad, 0, false); - ath_tx_complete_buf(sc, bf, txq, - &bf_head, -- ts, 0, 0); -+ ts, 0, 1); - break; - } - -- ath9k_hw_cleartxdesc(sc->sc_ah, -- tbf->bf_desc); - fi->bf = tbf; -- } else { -- /* -- * Clear descriptor status words for -- * software retry -- */ -- ath9k_hw_cleartxdesc(sc->sc_ah, -- bf->bf_desc); - } - } - -@@ -778,7 +761,7 @@ static enum ATH_AGGR_STATUS ath_tx_form_ - if (!bf) - continue; - -- bf->bf_state.bf_type |= BUF_AMPDU; -+ bf->bf_state.bf_type = BUF_AMPDU | BUF_AGGR; - seqno = bf->bf_state.seqno; - if (!bf_first) - bf_first = bf; -@@ -805,8 +788,7 @@ static enum ATH_AGGR_STATUS ath_tx_form_ - } - - tx_info = IEEE80211_SKB_CB(bf->bf_mpdu); -- if (nframes && ((tx_info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) || -- !(tx_info->control.rates[0].flags & IEEE80211_TX_RC_MCS))) -+ if (nframes && (tx_info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE)) - break; - - /* do not exceed subframe limit */ -@@ -828,20 +810,17 @@ static enum ATH_AGGR_STATUS ath_tx_form_ - - nframes++; - bf->bf_next = NULL; -- ath9k_hw_set_desc_link(sc->sc_ah, bf->bf_desc, 0); - - /* link buffers of this frame to the aggregate */ - if (!fi->retries) - ath_tx_addto_baw(sc, tid, seqno); -- ath9k_hw_set11n_aggr_middle(sc->sc_ah, bf->bf_desc, ndelim); -+ bf->bf_state.ndelim = ndelim; - - __skb_unlink(skb, &tid->buf_q); - list_add_tail(&bf->list, bf_q); -- if (bf_prev) { -+ if (bf_prev) - bf_prev->bf_next = bf; -- ath9k_hw_set_desc_link(sc->sc_ah, bf_prev->bf_desc, -- bf->bf_daddr); -- } -+ - bf_prev = bf; - - } while (!skb_queue_empty(&tid->buf_q)); -@@ -852,12 +831,245 @@ static enum ATH_AGGR_STATUS ath_tx_form_ - #undef PADBYTES - } - -+/* -+ * rix - rate index -+ * pktlen - total bytes (delims + data + fcs + pads + pad delims) -+ * width - 0 for 20 MHz, 1 for 40 MHz -+ * half_gi - to use 4us v/s 3.6 us for symbol time -+ */ -+static u32 ath_pkt_duration(struct ath_softc *sc, u8 rix, int pktlen, -+ int width, int half_gi, bool shortPreamble) -+{ -+ u32 nbits, nsymbits, duration, nsymbols; -+ int streams; -+ -+ /* find number of symbols: PLCP + data */ -+ streams = HT_RC_2_STREAMS(rix); -+ nbits = (pktlen << 3) + OFDM_PLCP_BITS; -+ nsymbits = bits_per_symbol[rix % 8][width] * streams; -+ nsymbols = (nbits + nsymbits - 1) / nsymbits; -+ -+ if (!half_gi) -+ duration = SYMBOL_TIME(nsymbols); -+ else -+ duration = SYMBOL_TIME_HALFGI(nsymbols); -+ -+ /* addup duration for legacy/ht training and signal fields */ -+ duration += L_STF + L_LTF + L_SIG + HT_SIG + HT_STF + HT_LTF(streams); -+ -+ return duration; -+} -+ -+static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, -+ struct ath_tx_info *info, int len) -+{ -+ struct ath_hw *ah = sc->sc_ah; -+ struct sk_buff *skb; -+ struct ieee80211_tx_info *tx_info; -+ struct ieee80211_tx_rate *rates; -+ const struct ieee80211_rate *rate; -+ struct ieee80211_hdr *hdr; -+ int i; -+ u8 rix = 0; -+ -+ skb = bf->bf_mpdu; -+ tx_info = IEEE80211_SKB_CB(skb); -+ rates = tx_info->control.rates; -+ hdr = (struct ieee80211_hdr *)skb->data; -+ -+ /* set dur_update_en for l-sig computation except for PS-Poll frames */ -+ info->dur_update = !ieee80211_is_pspoll(hdr->frame_control); -+ -+ /* -+ * We check if Short Preamble is needed for the CTS rate by -+ * checking the BSS's global flag. -+ * But for the rate series, IEEE80211_TX_RC_USE_SHORT_PREAMBLE is used. -+ */ -+ rate = ieee80211_get_rts_cts_rate(sc->hw, tx_info); -+ info->rtscts_rate = rate->hw_value; -+ if (sc->sc_flags & SC_OP_PREAMBLE_SHORT) -+ info->rtscts_rate |= rate->hw_value_short; -+ -+ for (i = 0; i < 4; i++) { -+ bool is_40, is_sgi, is_sp; -+ int phy; -+ -+ if (!rates[i].count || (rates[i].idx < 0)) -+ continue; -+ -+ rix = rates[i].idx; -+ info->rates[i].Tries = rates[i].count; -+ -+ if (rates[i].flags & IEEE80211_TX_RC_USE_RTS_CTS) { -+ info->rates[i].RateFlags |= ATH9K_RATESERIES_RTS_CTS; -+ info->flags |= ATH9K_TXDESC_RTSENA; -+ } else if (rates[i].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) { -+ info->rates[i].RateFlags |= ATH9K_RATESERIES_RTS_CTS; -+ info->flags |= ATH9K_TXDESC_CTSENA; -+ } -+ -+ if (rates[i].flags & IEEE80211_TX_RC_40_MHZ_WIDTH) -+ info->rates[i].RateFlags |= ATH9K_RATESERIES_2040; -+ if (rates[i].flags & IEEE80211_TX_RC_SHORT_GI) -+ info->rates[i].RateFlags |= ATH9K_RATESERIES_HALFGI; -+ -+ is_sgi = !!(rates[i].flags & IEEE80211_TX_RC_SHORT_GI); -+ is_40 = !!(rates[i].flags & IEEE80211_TX_RC_40_MHZ_WIDTH); -+ is_sp = !!(rates[i].flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE); -+ -+ if (rates[i].flags & IEEE80211_TX_RC_MCS) { -+ /* MCS rates */ -+ info->rates[i].Rate = rix | 0x80; -+ info->rates[i].ChSel = ath_txchainmask_reduction(sc, -+ ah->txchainmask, info->rates[i].Rate); -+ info->rates[i].PktDuration = ath_pkt_duration(sc, rix, len, -+ is_40, is_sgi, is_sp); -+ if (rix < 8 && (tx_info->flags & IEEE80211_TX_CTL_STBC)) -+ info->rates[i].RateFlags |= ATH9K_RATESERIES_STBC; -+ continue; -+ } -+ -+ /* legacy rates */ -+ if ((tx_info->band == IEEE80211_BAND_2GHZ) && -+ !(rate->flags & IEEE80211_RATE_ERP_G)) -+ phy = WLAN_RC_PHY_CCK; -+ else -+ phy = WLAN_RC_PHY_OFDM; -+ -+ rate = &sc->sbands[tx_info->band].bitrates[rates[i].idx]; -+ info->rates[i].Rate = rate->hw_value; -+ if (rate->hw_value_short) { -+ if (rates[i].flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) -+ info->rates[i].Rate |= rate->hw_value_short; -+ } else { -+ is_sp = false; -+ } -+ -+ if (bf->bf_state.bfs_paprd) -+ info->rates[i].ChSel = ah->txchainmask; -+ else -+ info->rates[i].ChSel = ath_txchainmask_reduction(sc, -+ ah->txchainmask, info->rates[i].Rate); -+ -+ info->rates[i].PktDuration = ath9k_hw_computetxtime(sc->sc_ah, -+ phy, rate->bitrate * 100, len, rix, is_sp); -+ } -+ -+ /* For AR5416 - RTS cannot be followed by a frame larger than 8K */ -+ if (bf_isaggr(bf) && (len > sc->sc_ah->caps.rts_aggr_limit)) -+ info->flags &= ~ATH9K_TXDESC_RTSENA; -+ -+ /* ATH9K_TXDESC_RTSENA and ATH9K_TXDESC_CTSENA are mutually exclusive. */ -+ if (info->flags & ATH9K_TXDESC_RTSENA) -+ info->flags &= ~ATH9K_TXDESC_CTSENA; -+} -+ -+static enum ath9k_pkt_type get_hw_packet_type(struct sk_buff *skb) -+{ -+ struct ieee80211_hdr *hdr; -+ enum ath9k_pkt_type htype; -+ __le16 fc; -+ -+ hdr = (struct ieee80211_hdr *)skb->data; -+ fc = hdr->frame_control; -+ -+ if (ieee80211_is_beacon(fc)) -+ htype = ATH9K_PKT_TYPE_BEACON; -+ else if (ieee80211_is_probe_resp(fc)) -+ htype = ATH9K_PKT_TYPE_PROBE_RESP; -+ else if (ieee80211_is_atim(fc)) -+ htype = ATH9K_PKT_TYPE_ATIM; -+ else if (ieee80211_is_pspoll(fc)) -+ htype = ATH9K_PKT_TYPE_PSPOLL; -+ else -+ htype = ATH9K_PKT_TYPE_NORMAL; -+ -+ return htype; -+} -+ -+static void ath_tx_fill_desc(struct ath_softc *sc, struct ath_buf *bf, -+ struct ath_txq *txq, int len) -+{ -+ struct ath_hw *ah = sc->sc_ah; -+ struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(bf->bf_mpdu); -+ struct ath_buf *bf_first = bf; -+ struct ath_tx_info info; -+ bool aggr = !!(bf->bf_state.bf_type & BUF_AGGR); -+ -+ memset(&info, 0, sizeof(info)); -+ info.is_first = true; -+ info.is_last = true; -+ info.txpower = MAX_RATE_POWER; -+ info.qcu = txq->axq_qnum; -+ -+ info.flags = ATH9K_TXDESC_INTREQ; -+ if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK) -+ info.flags |= ATH9K_TXDESC_NOACK; -+ if (tx_info->flags & IEEE80211_TX_CTL_LDPC) -+ info.flags |= ATH9K_TXDESC_LDPC; -+ -+ ath_buf_set_rate(sc, bf, &info, len); -+ -+ if (tx_info->flags & IEEE80211_TX_CTL_CLEAR_PS_FILT) -+ info.flags |= ATH9K_TXDESC_CLRDMASK; -+ -+ if (bf->bf_state.bfs_paprd) -+ info.flags |= (u32) bf->bf_state.bfs_paprd << ATH9K_TXDESC_PAPRD_S; -+ -+ -+ while (bf) { -+ struct sk_buff *skb = bf->bf_mpdu; -+ struct ath_frame_info *fi = get_frame_info(skb); -+ struct ieee80211_hdr *hdr; -+ int padpos, padsize; -+ -+ info.type = get_hw_packet_type(skb); -+ if (bf->bf_next) -+ info.link = bf->bf_next->bf_daddr; -+ else -+ info.link = 0; -+ -+ if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) { -+ hdr = (struct ieee80211_hdr *)skb->data; -+ padpos = ath9k_cmn_padpos(hdr->frame_control); -+ padsize = padpos & 3; -+ -+ info.buf_addr[0] = bf->bf_buf_addr; -+ info.buf_len[0] = padpos + padsize; -+ info.buf_addr[1] = info.buf_addr[0] + padpos; -+ info.buf_len[1] = skb->len - padpos; -+ } else { -+ info.buf_addr[0] = bf->bf_buf_addr; -+ info.buf_len[0] = skb->len; -+ } -+ -+ info.pkt_len = fi->framelen; -+ info.keyix = fi->keyix; -+ info.keytype = fi->keytype; -+ -+ if (aggr) { -+ if (bf == bf_first) -+ info.aggr = AGGR_BUF_FIRST; -+ else if (!bf->bf_next) -+ info.aggr = AGGR_BUF_LAST; -+ else -+ info.aggr = AGGR_BUF_MIDDLE; -+ -+ info.ndelim = bf->bf_state.ndelim; -+ info.aggr_len = len; -+ } -+ -+ ath9k_hw_set_txdesc(ah, bf->bf_desc, &info); -+ bf = bf->bf_next; -+ } -+} -+ - static void ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq, - struct ath_atx_tid *tid) - { - struct ath_buf *bf; - enum ATH_AGGR_STATUS status; -- struct ath_frame_info *fi; -+ struct ieee80211_tx_info *tx_info; - struct list_head bf_q; - int aggr_len; - -@@ -878,34 +1090,25 @@ static void ath_tx_sched_aggr(struct ath - - bf = list_first_entry(&bf_q, struct ath_buf, list); - bf->bf_lastbf = list_entry(bf_q.prev, struct ath_buf, list); -+ tx_info = IEEE80211_SKB_CB(bf->bf_mpdu); - - if (tid->ac->clear_ps_filter) { - tid->ac->clear_ps_filter = false; -- ath9k_hw_set_clrdmask(sc->sc_ah, bf->bf_desc, true); -+ tx_info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT; -+ } else { -+ tx_info->flags &= ~IEEE80211_TX_CTL_CLEAR_PS_FILT; - } - - /* if only one frame, send as non-aggregate */ - if (bf == bf->bf_lastbf) { -- fi = get_frame_info(bf->bf_mpdu); -- -- bf->bf_state.bf_type &= ~BUF_AGGR; -- ath9k_hw_clr11n_aggr(sc->sc_ah, bf->bf_desc); -- ath_buf_set_rate(sc, bf, fi->framelen); -- ath_tx_txqaddbuf(sc, txq, &bf_q, false); -- continue; -+ aggr_len = get_frame_info(bf->bf_mpdu)->framelen; -+ bf->bf_state.bf_type = BUF_AMPDU; -+ } else { -+ TX_STAT_INC(txq->axq_qnum, a_aggr); - } - -- /* setup first desc of aggregate */ -- bf->bf_state.bf_type |= BUF_AGGR; -- ath_buf_set_rate(sc, bf, aggr_len); -- ath9k_hw_set11n_aggr_first(sc->sc_ah, bf->bf_desc, aggr_len); -- -- /* anchor last desc of aggregate */ -- ath9k_hw_set11n_aggr_last(sc->sc_ah, bf->bf_lastbf->bf_desc); -- -+ ath_tx_fill_desc(sc, bf, txq, aggr_len); - ath_tx_txqaddbuf(sc, txq, &bf_q, false); -- TX_STAT_INC(txq->axq_qnum, a_aggr); -- - } while (txq->axq_ampdu_depth < ATH_AGGR_MIN_QDEPTH && - status != ATH_AGGR_BAW_CLOSED); - } -@@ -1483,7 +1686,7 @@ static void ath_tx_send_ampdu(struct ath - if (!bf) - return; - -- bf->bf_state.bf_type |= BUF_AMPDU; -+ bf->bf_state.bf_type = BUF_AMPDU; - INIT_LIST_HEAD(&bf_head); - list_add(&bf->list, &bf_head); - -@@ -1493,7 +1696,7 @@ static void ath_tx_send_ampdu(struct ath - /* Queue to h/w without aggregation */ - TX_STAT_INC(txctl->txq->axq_qnum, a_queued_hw); - bf->bf_lastbf = bf; -- ath_buf_set_rate(sc, bf, fi->framelen); -+ ath_tx_fill_desc(sc, bf, txctl->txq, fi->framelen); - ath_tx_txqaddbuf(sc, txctl->txq, &bf_head, false); - } - -@@ -1513,41 +1716,18 @@ static void ath_tx_send_normal(struct at - - INIT_LIST_HEAD(&bf_head); - list_add_tail(&bf->list, &bf_head); -- bf->bf_state.bf_type &= ~BUF_AMPDU; -+ 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_buf_set_rate(sc, bf, fi->framelen); -+ ath_tx_fill_desc(sc, bf, txq, fi->framelen); - ath_tx_txqaddbuf(sc, txq, &bf_head, false); - TX_STAT_INC(txq->axq_qnum, queued); - } - --static enum ath9k_pkt_type get_hw_packet_type(struct sk_buff *skb) --{ -- struct ieee80211_hdr *hdr; -- enum ath9k_pkt_type htype; -- __le16 fc; -- -- hdr = (struct ieee80211_hdr *)skb->data; -- fc = hdr->frame_control; -- -- if (ieee80211_is_beacon(fc)) -- htype = ATH9K_PKT_TYPE_BEACON; -- else if (ieee80211_is_probe_resp(fc)) -- htype = ATH9K_PKT_TYPE_PROBE_RESP; -- else if (ieee80211_is_atim(fc)) -- htype = ATH9K_PKT_TYPE_ATIM; -- else if (ieee80211_is_pspoll(fc)) -- htype = ATH9K_PKT_TYPE_PSPOLL; -- else -- htype = ATH9K_PKT_TYPE_NORMAL; -- -- return htype; --} -- - static void setup_frame_info(struct ieee80211_hw *hw, struct sk_buff *skb, - int framelen) - { -@@ -1575,51 +1755,6 @@ static void setup_frame_info(struct ieee - fi->framelen = framelen; - } - --static int setup_tx_flags(struct sk_buff *skb) --{ -- struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); -- int flags = 0; -- -- flags |= ATH9K_TXDESC_INTREQ; -- -- if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK) -- flags |= ATH9K_TXDESC_NOACK; -- -- if (tx_info->flags & IEEE80211_TX_CTL_LDPC) -- flags |= ATH9K_TXDESC_LDPC; -- -- return flags; --} -- --/* -- * rix - rate index -- * pktlen - total bytes (delims + data + fcs + pads + pad delims) -- * width - 0 for 20 MHz, 1 for 40 MHz -- * half_gi - to use 4us v/s 3.6 us for symbol time -- */ --static u32 ath_pkt_duration(struct ath_softc *sc, u8 rix, int pktlen, -- int width, int half_gi, bool shortPreamble) --{ -- u32 nbits, nsymbits, duration, nsymbols; -- int streams; -- -- /* find number of symbols: PLCP + data */ -- streams = HT_RC_2_STREAMS(rix); -- nbits = (pktlen << 3) + OFDM_PLCP_BITS; -- nsymbits = bits_per_symbol[rix % 8][width] * streams; -- nsymbols = (nbits + nsymbits - 1) / nsymbits; -- -- if (!half_gi) -- duration = SYMBOL_TIME(nsymbols); -- else -- duration = SYMBOL_TIME_HALFGI(nsymbols); -- -- /* addup duration for legacy/ht training and signal fields */ -- duration += L_STF + L_LTF + L_SIG + HT_SIG + HT_STF + HT_LTF(streams); -- -- return duration; --} -- - u8 ath_txchainmask_reduction(struct ath_softc *sc, u8 chainmask, u32 rate) - { - struct ath_hw *ah = sc->sc_ah; -@@ -1632,118 +1767,6 @@ u8 ath_txchainmask_reduction(struct ath_ - return chainmask; + !(sc->ps_flags & (PS_WAIT_FOR_BEACON | +@@ -332,7 +332,8 @@ static int ath_reset_internal(struct ath + hchan = ah->curchan; + } + +- if (fastcc && !ath9k_hw_check_alive(ah)) ++ if (fastcc && (ah->chip_fullsleep || ++ !ath9k_hw_check_alive(ah))) + fastcc = false; + + if (!ath_prepare_reset(sc, retry_tx, flush)) +@@ -882,82 +883,6 @@ chip_reset: + #undef SCHED_INTR } --static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, int len) +-static void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw) -{ - struct ath_hw *ah = sc->sc_ah; -- struct ath9k_11n_rate_series series[4]; -- struct sk_buff *skb; -- struct ieee80211_tx_info *tx_info; -- struct ieee80211_tx_rate *rates; -- const struct ieee80211_rate *rate; -- struct ieee80211_hdr *hdr; -- int i, flags = 0; -- u8 rix = 0, ctsrate = 0; -- bool is_pspoll; +- struct ath_common *common = ath9k_hw_common(ah); +- struct ieee80211_channel *channel = hw->conf.channel; +- int r; - -- memset(series, 0, sizeof(struct ath9k_11n_rate_series) * 4); -- -- skb = bf->bf_mpdu; -- tx_info = IEEE80211_SKB_CB(skb); -- rates = tx_info->control.rates; -- hdr = (struct ieee80211_hdr *)skb->data; -- is_pspoll = ieee80211_is_pspoll(hdr->frame_control); +- ath9k_ps_wakeup(sc); +- spin_lock_bh(&sc->sc_pcu_lock); +- atomic_set(&ah->intr_ref_cnt, -1); - -- /* -- * We check if Short Preamble is needed for the CTS rate by -- * checking the BSS's global flag. -- * But for the rate series, IEEE80211_TX_RC_USE_SHORT_PREAMBLE is used. -- */ -- rate = ieee80211_get_rts_cts_rate(sc->hw, tx_info); -- ctsrate = rate->hw_value; -- if (sc->sc_flags & SC_OP_PREAMBLE_SHORT) -- ctsrate |= rate->hw_value_short; +- ath9k_hw_configpcipowersave(ah, false); - -- for (i = 0; i < 4; i++) { -- bool is_40, is_sgi, is_sp; -- int phy; +- if (!ah->curchan) +- ah->curchan = ath9k_cmn_get_curchannel(sc->hw, ah); - -- if (!rates[i].count || (rates[i].idx < 0)) -- continue; +- r = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false); +- if (r) { +- ath_err(common, +- "Unable to reset channel (%u MHz), reset status %d\n", +- channel->center_freq, r); +- } - -- rix = rates[i].idx; -- series[i].Tries = rates[i].count; +- ath_complete_reset(sc, true); - -- if (rates[i].flags & IEEE80211_TX_RC_USE_RTS_CTS) { -- series[i].RateFlags |= ATH9K_RATESERIES_RTS_CTS; -- flags |= ATH9K_TXDESC_RTSENA; -- } else if (rates[i].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) { -- series[i].RateFlags |= ATH9K_RATESERIES_RTS_CTS; -- flags |= ATH9K_TXDESC_CTSENA; -- } +- /* Enable LED */ +- ath9k_hw_cfg_output(ah, ah->led_pin, +- AR_GPIO_OUTPUT_MUX_AS_OUTPUT); +- ath9k_hw_set_gpio(ah, ah->led_pin, 0); - -- if (rates[i].flags & IEEE80211_TX_RC_40_MHZ_WIDTH) -- series[i].RateFlags |= ATH9K_RATESERIES_2040; -- if (rates[i].flags & IEEE80211_TX_RC_SHORT_GI) -- series[i].RateFlags |= ATH9K_RATESERIES_HALFGI; +- spin_unlock_bh(&sc->sc_pcu_lock); - -- is_sgi = !!(rates[i].flags & IEEE80211_TX_RC_SHORT_GI); -- is_40 = !!(rates[i].flags & IEEE80211_TX_RC_40_MHZ_WIDTH); -- is_sp = !!(rates[i].flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE); +- ath9k_ps_restore(sc); +-} - -- if (rates[i].flags & IEEE80211_TX_RC_MCS) { -- /* MCS rates */ -- series[i].Rate = rix | 0x80; -- series[i].ChSel = ath_txchainmask_reduction(sc, -- ah->txchainmask, series[i].Rate); -- series[i].PktDuration = ath_pkt_duration(sc, rix, len, -- is_40, is_sgi, is_sp); -- if (rix < 8 && (tx_info->flags & IEEE80211_TX_CTL_STBC)) -- series[i].RateFlags |= ATH9K_RATESERIES_STBC; -- continue; -- } +-void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw) +-{ +- struct ath_hw *ah = sc->sc_ah; +- struct ieee80211_channel *channel = hw->conf.channel; +- int r; - -- /* legacy rates */ -- if ((tx_info->band == IEEE80211_BAND_2GHZ) && -- !(rate->flags & IEEE80211_RATE_ERP_G)) -- phy = WLAN_RC_PHY_CCK; -- else -- phy = WLAN_RC_PHY_OFDM; +- ath9k_ps_wakeup(sc); - -- rate = &sc->sbands[tx_info->band].bitrates[rates[i].idx]; -- series[i].Rate = rate->hw_value; -- if (rate->hw_value_short) { -- if (rates[i].flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) -- series[i].Rate |= rate->hw_value_short; -- } else { -- is_sp = false; -- } +- ath_cancel_work(sc); - -- if (bf->bf_state.bfs_paprd) -- series[i].ChSel = ah->txchainmask; -- else -- series[i].ChSel = ath_txchainmask_reduction(sc, -- ah->txchainmask, series[i].Rate); +- spin_lock_bh(&sc->sc_pcu_lock); - -- series[i].PktDuration = ath9k_hw_computetxtime(sc->sc_ah, -- phy, rate->bitrate * 100, len, rix, is_sp); +- /* +- * Keep the LED on when the radio is disabled +- * during idle unassociated state. +- */ +- if (!sc->ps_idle) { +- ath9k_hw_set_gpio(ah, ah->led_pin, 1); +- ath9k_hw_cfg_gpio_input(ah, ah->led_pin); - } - -- /* For AR5416 - RTS cannot be followed by a frame larger than 8K */ -- if (bf_isaggr(bf) && (len > sc->sc_ah->caps.rts_aggr_limit)) -- flags &= ~ATH9K_TXDESC_RTSENA; +- ath_prepare_reset(sc, false, true); +- +- if (!ah->curchan) +- ah->curchan = ath9k_cmn_get_curchannel(hw, ah); - -- /* ATH9K_TXDESC_RTSENA and ATH9K_TXDESC_CTSENA are mutually exclusive. */ -- if (flags & ATH9K_TXDESC_RTSENA) -- flags &= ~ATH9K_TXDESC_CTSENA; +- r = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false); +- if (r) { +- ath_err(ath9k_hw_common(sc->sc_ah), +- "Unable to reset channel (%u MHz), reset status %d\n", +- channel->center_freq, r); +- } +- +- ath9k_hw_phy_disable(ah); - -- /* set dur_update_en for l-sig computation except for PS-Poll frames */ -- ath9k_hw_set11n_ratescenario(sc->sc_ah, bf->bf_desc, -- bf->bf_lastbf->bf_desc, -- !is_pspoll, ctsrate, -- 0, series, 4, flags); +- ath9k_hw_configpcipowersave(ah, true); - +- spin_unlock_bh(&sc->sc_pcu_lock); +- ath9k_ps_restore(sc); -} - - /* - * Assign a descriptor (and sequence number if necessary, - * and map buffer for DMA. Frees skb on error -@@ -1753,13 +1776,10 @@ static struct ath_buf *ath_tx_setup_buff - struct ath_atx_tid *tid, - struct sk_buff *skb) + static int ath_reset(struct ath_softc *sc, bool retry_tx) { -- struct ath_hw *ah = sc->sc_ah; - struct ath_common *common = ath9k_hw_common(sc->sc_ah); - struct ath_frame_info *fi = get_frame_info(skb); - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; - struct ath_buf *bf; -- struct ath_desc *ds; -- int frm_type; - u16 seqno; - - bf = ath_tx_get_buffer(sc); -@@ -1777,7 +1797,6 @@ static struct ath_buf *ath_tx_setup_buff - bf->bf_state.seqno = seqno; + int r; +@@ -1093,6 +1018,9 @@ static int ath9k_start(struct ieee80211_ + * and then setup of the interrupt mask. + */ + spin_lock_bh(&sc->sc_pcu_lock); ++ ++ atomic_set(&ah->intr_ref_cnt, -1); ++ + 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_ + goto mutex_unlock; + } + ++ if (ah->led_pin >= 0) { ++ ath9k_hw_cfg_output(ah, ah->led_pin, ++ AR_GPIO_OUTPUT_MUX_AS_OUTPUT); ++ ath9k_hw_set_gpio(ah, ah->led_pin, 0); ++ } ++ ++ /* ++ * Reset key cache to sane defaults (all entries cleared) instead of ++ * semi-random values after suspend/resume. ++ */ ++ ath9k_cmn_init_crypto(sc->sc_ah); ++ + 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 + } } -- bf->bf_flags = setup_tx_flags(skb); - bf->bf_mpdu = skb; ++ /* ++ * Cannot tx while the hardware is in full sleep, it first needs a full ++ * chip reset to recover from that ++ */ ++ if (unlikely(sc->sc_ah->power_mode == ATH9K_PM_FULL_SLEEP)) ++ goto exit; ++ + 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_ + struct ath_softc *sc = hw->priv; + struct ath_hw *ah = sc->sc_ah; + struct ath_common *common = ath9k_hw_common(ah); ++ bool prev_idle; + + mutex_lock(&sc->mutex); + +@@ -1252,35 +1200,45 @@ static void ath9k_stop(struct ieee80211_ + * before setting the invalid flag. */ + ath9k_hw_disable_interrupts(ah); + +- if (!(sc->sc_flags & SC_OP_INVALID)) { +- ath_drain_all_txq(sc, false); +- ath_stoprecv(sc); +- ath9k_hw_phy_disable(ah); +- } else +- sc->rx.rxlink = NULL; ++ spin_unlock_bh(&sc->sc_pcu_lock); ++ ++ /* we can now sync irq and kill any running tasklets, since we already ++ * disabled interrupts and not holding a spin lock */ ++ synchronize_irq(sc->irq); ++ tasklet_kill(&sc->intr_tq); ++ tasklet_kill(&sc->bcon_tasklet); ++ ++ prev_idle = sc->ps_idle; ++ sc->ps_idle = true; ++ ++ spin_lock_bh(&sc->sc_pcu_lock); ++ ++ if (ah->led_pin >= 0) { ++ ath9k_hw_set_gpio(ah, ah->led_pin, 1); ++ ath9k_hw_cfg_gpio_input(ah, ah->led_pin); ++ } ++ ++ ath_prepare_reset(sc, false, true); - bf->bf_buf_addr = dma_map_single(sc->dev, skb->data, -@@ -1791,22 +1810,6 @@ static struct ath_buf *ath_tx_setup_buff - goto error; + if (sc->rx.frag) { + dev_kfree_skb_any(sc->rx.frag); + sc->rx.frag = NULL; } -- frm_type = get_hw_packet_type(skb); -- -- ds = bf->bf_desc; -- ath9k_hw_set_desc_link(ah, ds, 0); -- -- ath9k_hw_set11n_txdesc(ah, ds, fi->framelen, frm_type, MAX_RATE_POWER, -- fi->keyix, fi->keytype, bf->bf_flags); -- -- ath9k_hw_filltxdesc(ah, ds, -- skb->len, /* segment length */ -- true, /* first segment */ -- true, /* last segment */ -- ds, /* first descriptor */ -- bf->bf_buf_addr, -- txq->axq_qnum); -- - fi->bf = bf; +- /* disable HAL and put h/w to sleep */ +- ath9k_hw_disable(ah); ++ if (!ah->curchan) ++ ah->curchan = ath9k_cmn_get_curchannel(hw, ah); - return bf; -@@ -1849,16 +1852,9 @@ static void ath_tx_start_dma(struct ath_ +- spin_unlock_bh(&sc->sc_pcu_lock); ++ ath9k_hw_reset(ah, ah->curchan, ah->caldata, false); ++ ath9k_hw_phy_disable(ah); - bf->bf_state.bfs_paprd = txctl->paprd; +- /* we can now sync irq and kill any running tasklets, since we already +- * disabled interrupts and not holding a spin lock */ +- synchronize_irq(sc->irq); +- tasklet_kill(&sc->intr_tq); +- tasklet_kill(&sc->bcon_tasklet); ++ ath9k_hw_configpcipowersave(ah, true); -- if (bf->bf_state.bfs_paprd) -- ar9003_hw_set_paprd_txdesc(sc->sc_ah, bf->bf_desc, -- bf->bf_state.bfs_paprd); -- - if (txctl->paprd) - bf->bf_state.bfs_paprd_timestamp = jiffies; +- ath9k_ps_restore(sc); ++ spin_unlock_bh(&sc->sc_pcu_lock); + +- sc->ps_idle = true; +- ath_radio_disable(sc, hw); ++ ath9k_ps_restore(sc); + + sc->sc_flags |= SC_OP_INVALID; ++ sc->ps_idle = prev_idle; + + mutex_unlock(&sc->mutex); + +@@ -1620,8 +1578,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; +- bool disable_radio = false; + ++ ath9k_ps_wakeup(sc); + mutex_lock(&sc->mutex); -- if (tx_info->flags & IEEE80211_TX_CTL_CLEAR_PS_FILT) -- ath9k_hw_set_clrdmask(sc->sc_ah, bf->bf_desc, true); + /* +@@ -1632,13 +1590,8 @@ static int ath9k_config(struct ieee80211 + */ + if (changed & IEEE80211_CONF_CHANGE_IDLE) { + sc->ps_idle = !!(conf->flags & IEEE80211_CONF_IDLE); +- if (!sc->ps_idle) { +- ath_radio_enable(sc, hw); +- ath_dbg(common, ATH_DBG_CONFIG, +- "not-idle: enabling radio\n"); +- } else { +- disable_radio = true; +- } ++ if (sc->ps_idle) ++ ath_cancel_work(sc); + } + + /* +@@ -1745,18 +1698,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; +- ath9k_ps_wakeup(sc); + ath9k_cmn_update_txpow(ah, sc->curtxpow, + sc->config.txpowlimit, &sc->curtxpow); +- ath9k_ps_restore(sc); +- } - - ath_tx_send_normal(sc, txctl->txq, tid, skb); +- if (disable_radio) { +- ath_dbg(common, ATH_DBG_CONFIG, "idle: disabling radio\n"); +- ath_radio_disable(sc, hw); } -@@ -1899,15 +1895,18 @@ int ath_tx_start(struct ieee80211_hw *hw - hdr->seq_ctrl |= cpu_to_le16(sc->tx.seq_no); + mutex_unlock(&sc->mutex); ++ ath9k_ps_restore(sc); + + return 0; + } +@@ -2324,9 +2271,6 @@ static void ath9k_flush(struct ieee80211 + return; } -- /* Add the padding after the header if this is not already done */ -- padpos = ath9k_cmn_padpos(hdr->frame_control); -- padsize = padpos & 3; -- if (padsize && skb->len > padpos) { -- if (skb_headroom(skb) < padsize) -- return -ENOMEM; +- if (drop) +- timeout = 1; - -- skb_push(skb, padsize); -- memmove(skb->data, skb->data + padsize, padpos); -+ if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)) { -+ /* Add the padding after the header if this is not already done */ -+ padpos = ath9k_cmn_padpos(hdr->frame_control); -+ padsize = padpos & 3; -+ if (padsize && skb->len > padpos) { -+ if (skb_headroom(skb) < padsize) -+ return -ENOMEM; -+ -+ skb_push(skb, padsize); -+ memmove(skb->data, skb->data + padsize, padpos); -+ hdr = (struct ieee80211_hdr *) skb->data; -+ } + for (j = 0; j < timeout; j++) { + bool npend = false; + +@@ -2344,21 +2288,22 @@ static void ath9k_flush(struct ieee80211 + } + + if (!npend) +- goto out; ++ break; } - if ((vif && vif->type != NL80211_IFTYPE_AP && -@@ -1953,20 +1952,21 @@ static void ath_tx_complete(struct ath_s - if (tx_flags & ATH_TX_BAR) - tx_info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK; +- ath9k_ps_wakeup(sc); +- spin_lock_bh(&sc->sc_pcu_lock); +- drain_txq = ath_drain_all_txq(sc, false); +- spin_unlock_bh(&sc->sc_pcu_lock); ++ if (drop) { ++ ath9k_ps_wakeup(sc); ++ spin_lock_bh(&sc->sc_pcu_lock); ++ drain_txq = ath_drain_all_txq(sc, false); ++ spin_unlock_bh(&sc->sc_pcu_lock); + +- if (!drain_txq) +- ath_reset(sc, false); ++ if (!drain_txq) ++ ath_reset(sc, false); + +- ath9k_ps_restore(sc); +- ieee80211_wake_queues(hw); ++ ath9k_ps_restore(sc); ++ ieee80211_wake_queues(hw); ++ } -- if (!(tx_flags & (ATH_TX_ERROR | ATH_TX_XRETRY))) { -+ if (!(tx_flags & ATH_TX_ERROR)) - /* Frame was ACKed */ - tx_info->flags |= IEEE80211_TX_STAT_ACK; -- } +-out: + ieee80211_queue_delayed_work(hw, &sc->tx_complete_work, 0); + mutex_unlock(&sc->mutex); + } +--- a/drivers/net/wireless/ath/ath9k/pci.c ++++ b/drivers/net/wireless/ath/ath9k/pci.c +@@ -307,12 +307,11 @@ static int ath_pci_suspend(struct device + struct ieee80211_hw *hw = pci_get_drvdata(pdev); + struct ath_softc *sc = hw->priv; -- padpos = ath9k_cmn_padpos(hdr->frame_control); -- padsize = padpos & 3; -- if (padsize && skb->len>padpos+padsize) { -- /* -- * Remove MAC header padding before giving the frame back to -- * mac80211. -- */ -- memmove(skb->data + padsize, skb->data, padpos); -- skb_pull(skb, padsize); -+ if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)) { -+ padpos = ath9k_cmn_padpos(hdr->frame_control); -+ padsize = padpos & 3; -+ if (padsize && skb->len>padpos+padsize) { -+ /* -+ * Remove MAC header padding before giving the frame back to -+ * mac80211. -+ */ -+ memmove(skb->data + padsize, skb->data, padpos); -+ skb_pull(skb, padsize); -+ } +- ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 1); +- + /* The device has to be moved to FULLSLEEP forcibly. + * Otherwise the chip never moved to full sleep, + * when no interface is up. + */ ++ ath9k_hw_disable(sc->sc_ah); + ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_FULL_SLEEP); + + return 0; +@@ -334,22 +333,6 @@ static int ath_pci_resume(struct device + if ((val & 0x0000ff00) != 0) + pci_write_config_dword(pdev, 0x40, val & 0xffff00ff); + +- ath9k_ps_wakeup(sc); +- /* Enable LED */ +- ath9k_hw_cfg_output(sc->sc_ah, sc->sc_ah->led_pin, +- AR_GPIO_OUTPUT_MUX_AS_OUTPUT); +- ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 0); +- +- /* +- * Reset key cache to sane defaults (all entries cleared) instead of +- * semi-random values after suspend/resume. +- */ +- ath9k_cmn_init_crypto(sc->sc_ah); +- ath9k_ps_restore(sc); +- +- sc->ps_idle = true; +- ath_radio_disable(sc, hw); +- + return 0; + } + +--- 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 (sc->ps_flags & PS_WAIT_FOR_TX_ACK) { -@@ -2000,18 +2000,18 @@ static void ath_tx_complete_buf(struct a - struct ath_tx_status *ts, int txok, int sendbar) - { - 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 (tid->baw_head == tid->baw_tail) { ++ tid->state &= ~AGGR_ADDBA_COMPLETE; ++ tid->state &= ~AGGR_CLEANUP; ++ } ++ + spin_unlock_bh(&txq->axq_lock); + } - if (sendbar) - tx_flags = ATH_TX_BAR; +@@ -556,15 +561,9 @@ static void ath_tx_complete_aggr(struct + spin_unlock_bh(&txq->axq_lock); + } -- if (!txok) { -+ if (!txok) - tx_flags |= ATH_TX_ERROR; +- if (tid->state & AGGR_CLEANUP) { ++ if (tid->state & AGGR_CLEANUP) + ath_tx_flush_tid(sc, tid); -- if (bf_isxretried(bf)) -- tx_flags |= ATH_TX_XRETRY; +- if (tid->baw_head == tid->baw_tail) { +- tid->state &= ~AGGR_ADDBA_COMPLETE; +- tid->state &= ~AGGR_CLEANUP; +- } - } -+ if (ts->ts_status & ATH9K_TXERR_FILT) -+ tx_info->flags |= IEEE80211_TX_STAT_TX_FILTERED; - - dma_unmap_single(sc->dev, bf->bf_buf_addr, skb->len, DMA_TO_DEVICE); - bf->bf_buf_addr = 0; -@@ -2024,7 +2024,7 @@ static void ath_tx_complete_buf(struct a - else - complete(&sc->paprd_complete); - } else { -- ath_debug_stat_tx(sc, bf, ts, txq); -+ ath_debug_stat_tx(sc, bf, ts, txq, tx_flags); - ath_tx_complete(sc, skb, tx_flags, txq); - } - /* At this point, skb (bf->bf_mpdu) is consumed...make sure we don't -@@ -2042,7 +2042,7 @@ static void ath_tx_complete_buf(struct a +- + rcu_read_unlock(); - static void ath_tx_rc_status(struct ath_softc *sc, struct ath_buf *bf, - struct ath_tx_status *ts, int nframes, int nbad, -- int txok, bool update_rc) -+ int txok) - { - struct sk_buff *skb = bf->bf_mpdu; - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; -@@ -2057,9 +2057,7 @@ static void ath_tx_rc_status(struct ath_ - tx_rateindex = ts->ts_rateindex; - WARN_ON(tx_rateindex >= hw->max_rates); - -- if (ts->ts_status & ATH9K_TXERR_FILT) -- tx_info->flags |= IEEE80211_TX_STAT_TX_FILTERED; -- if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && update_rc) { -+ if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) { - tx_info->flags |= IEEE80211_TX_STAT_AMPDU; - - BUG_ON(nbad > nframes); -@@ -2069,7 +2067,7 @@ static void ath_tx_rc_status(struct ath_ + if (needreset) { +@@ -1955,7 +1954,7 @@ static void ath_tx_complete(struct ath_s + skb_pull(skb, padsize); } - if ((ts->ts_status & ATH9K_TXERR_FILT) == 0 && -- (bf->bf_flags & ATH9K_TXDESC_NOACK) == 0 && update_rc) { -+ (tx_info->flags & IEEE80211_TX_CTL_NO_ACK) == 0) { - /* - * If an underrun error is seen assume it as an excessive - * retry only if max frame trigger level has been reached -@@ -2082,9 +2080,9 @@ static void ath_tx_rc_status(struct ath_ - * successfully by eventually preferring slower rates. - * This itself should also alleviate congestion on the bus. - */ -- if (ieee80211_is_data(hdr->frame_control) && -- (ts->ts_flags & (ATH9K_TX_DATA_UNDERRUN | -- ATH9K_TX_DELIM_UNDERRUN)) && -+ if (unlikely(ts->ts_flags & (ATH9K_TX_DATA_UNDERRUN | -+ ATH9K_TX_DELIM_UNDERRUN)) && -+ ieee80211_is_data(hdr->frame_control) && - ah->tx_trig_level >= sc->sc_ah->config.max_txtrig_level) - tx_info->status.rates[tx_rateindex].count = - hw->max_rate_tries; -@@ -2115,13 +2113,7 @@ static void ath_tx_process_buffer(struct - spin_unlock_bh(&txq->axq_lock); +- if (sc->ps_flags & PS_WAIT_FOR_TX_ACK) { ++ if ((sc->ps_flags & PS_WAIT_FOR_TX_ACK) && !txq->axq_depth) { + 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/net/cfg80211.h ++++ b/include/net/cfg80211.h +@@ -1130,6 +1130,7 @@ struct cfg80211_ibss_params { + u8 *ssid; + u8 *bssid; + struct ieee80211_channel *channel; ++ enum nl80211_channel_type channel_type; + u8 *ie; + u8 ssid_len, ie_len; + u16 beacon_interval; +@@ -3292,6 +3293,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 ++ * @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); ++ + /* Logging, debugging and troubleshooting/diagnostic helpers. */ - if (!bf_isampdu(bf)) { -- /* -- * This frame is sent out as a single frame. -- * Use hardware retry status for this frame. -- */ -- if (ts->ts_status & ATH9K_TXERR_XRETRY) -- bf->bf_state.bf_type |= BUF_XRETRY; -- ath_tx_rc_status(sc, bf, ts, 1, txok ? 0 : 1, txok, true); -+ ath_tx_rc_status(sc, bf, ts, 1, txok ? 0 : 1, txok); - ath_tx_complete_buf(sc, bf, txq, bf_head, ts, txok, 0); - } else - ath_tx_complete_aggr(sc, txq, bf, bf_head, ts, txok, true); + /* wiphy_printk helpers, similar to dev_printk */ --- a/net/mac80211/agg-rx.c +++ b/net/mac80211/agg-rx.c -@@ -180,6 +180,8 @@ static void ieee80211_send_addba_resp(st +@@ -182,6 +182,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); mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ACTION); --- a/net/mac80211/agg-tx.c +++ b/net/mac80211/agg-tx.c -@@ -77,7 +77,8 @@ static void ieee80211_send_addba_request - memcpy(mgmt->da, da, ETH_ALEN); +@@ -79,10 +79,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) -+ sdata->vif.type == NL80211_IFTYPE_AP_VLAN || + sdata->vif.type == NL80211_IFTYPE_AP_VLAN || +- sdata->vif.type == NL80211_IFTYPE_MESH_POINT) ++ sdata->vif.type == NL80211_IFTYPE_MESH_POINT || + sdata->vif.type == NL80211_IFTYPE_WDS) 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); -@@ -397,7 +398,8 @@ int ieee80211_start_tx_ba_session(struct - */ ++ else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) ++ memcpy(mgmt->bssid, sdata->u.ibss.bssid, ETH_ALEN); + + mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | + IEEE80211_STYPE_ACTION); +@@ -394,7 +397,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) return -EINVAL; - if (test_sta_flags(sta, WLAN_STA_BLOCK_BA)) { + if (test_sta_flag(sta, WLAN_STA_BLOCK_BA)) { --- a/net/mac80211/debugfs_sta.c +++ b/net/mac80211/debugfs_sta.c -@@ -59,7 +59,7 @@ static ssize_t sta_flags_read(struct fil - char buf[100]; - struct sta_info *sta = file->private_data; - u32 staflags = get_sta_flags(sta); -- int res = scnprintf(buf, sizeof(buf), "%s%s%s%s%s%s%s%s%s", -+ int res = scnprintf(buf, sizeof(buf), "%s%s%s%s%s%s%s%s", - staflags & WLAN_STA_AUTH ? "AUTH\n" : "", - staflags & WLAN_STA_ASSOC ? "ASSOC\n" : "", - staflags & WLAN_STA_PS_STA ? "PS (sta)\n" : "", -@@ -67,7 +67,6 @@ static ssize_t sta_flags_read(struct fil - staflags & WLAN_STA_AUTHORIZED ? "AUTHORIZED\n" : "", - staflags & WLAN_STA_SHORT_PREAMBLE ? "SHORT PREAMBLE\n" : "", - staflags & WLAN_STA_WME ? "WME\n" : "", -- staflags & WLAN_STA_WDS ? "WDS\n" : "", - staflags & WLAN_STA_MFP ? "MFP\n" : ""); - return simple_read_from_buffer(userbuf, count, ppos, buf, res); - } +@@ -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", + TEST(AUTH), TEST(ASSOC), TEST(PS_STA), + TEST(PS_DRIVER), TEST(AUTHORIZED), + TEST(SHORT_PREAMBLE), TEST(ASSOC_AP), +- TEST(WME), TEST(WDS), TEST(CLEAR_PS_FILT), ++ TEST(WME), TEST(CLEAR_PS_FILT), + TEST(MFP), TEST(BLOCK_BA), TEST(PSPOLL), + TEST(UAPSD), TEST(SP), TEST(TDLS_PEER), + TEST(TDLS_PEER_AUTH)); +--- a/net/mac80211/ht.c ++++ b/net/mac80211/ht.c +@@ -201,6 +201,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); ++ else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) ++ memcpy(mgmt->bssid, sdata->u.ibss.bssid, ETH_ALEN); + + mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | + IEEE80211_STYPE_ACTION); +--- a/net/mac80211/ibss.c ++++ b/net/mac80211/ibss.c +@@ -77,6 +77,7 @@ static void __ieee80211_sta_join_ibss(st + struct cfg80211_bss *bss; + u32 bss_change; + u8 supp_rates[IEEE80211_MAX_SUPP_RATES]; ++ enum nl80211_channel_type channel_type; + + lockdep_assert_held(&ifibss->mtx); + +@@ -105,8 +106,16 @@ static void __ieee80211_sta_join_ibss(st + + sdata->drop_unencrypted = capability & WLAN_CAPABILITY_PRIVACY ? 1 : 0; + +- local->oper_channel = chan; +- WARN_ON(!ieee80211_set_channel_type(local, sdata, NL80211_CHAN_NO_HT)); ++ channel_type = ifibss->channel_type; ++ if (channel_type > NL80211_CHAN_HT20 && ++ !cfg80211_can_beacon_sec_chan(local->hw.wiphy, chan, channel_type)) ++ channel_type = NL80211_CHAN_HT20; ++ if (!ieee80211_set_channel_type(local, sdata, channel_type)) { ++ /* can only fail due to HT40+/- mismatch */ ++ channel_type = NL80211_CHAN_HT20; ++ WARN_ON(!ieee80211_set_channel_type(local, sdata, ++ NL80211_CHAN_HT20)); ++ } + 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 + memcpy(skb_put(skb, ifibss->ie_len), + ifibss->ie, ifibss->ie_len); + ++ /* add HT capability and information IEs */ ++ if (channel_type && sband->ht_cap.ht_supported) { ++ 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_info(pos, ++ &sband->ht_cap, ++ chan, ++ channel_type); ++ } ++ + 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 + bss_change |= BSS_CHANGED_BEACON; + bss_change |= BSS_CHANGED_BEACON_ENABLED; + bss_change |= BSS_CHANGED_BASIC_RATES; ++ bss_change |= BSS_CHANGED_HT; + 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 + 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]; + + 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); ++ ++ /* 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); ++ } ++ } ++ } + + rcu_read_unlock(); + } +@@ -898,10 +957,15 @@ int ieee80211_ibss_join(struct ieee80211 + struct sk_buff *skb; + + skb = dev_alloc_skb(sdata->local->hw.extra_tx_headroom + +- 36 /* bitrates */ + +- 34 /* SSID */ + +- 3 /* DS params */ + +- 4 /* IBSS params */ + ++ sizeof(struct ieee80211_hdr_3addr) + ++ 12 /* struct ieee80211_mgmt.u.beacon */ + ++ 2 + IEEE80211_MAX_SSID_LEN /* max SSID */ + ++ 2 + 8 /* max Supported Rates */ + ++ 3 /* max DS params */ + ++ 4 /* IBSS params */ + ++ 2 + (IEEE80211_MAX_SUPP_RATES - 8) + ++ 2 + sizeof(struct ieee80211_ht_cap) + ++ 2 + sizeof(struct ieee80211_ht_info) + + params->ie_len); + if (!skb) + return -ENOMEM; +@@ -922,13 +986,15 @@ int ieee80211_ibss_join(struct ieee80211 + sdata->vif.bss_conf.beacon_int = params->beacon_interval; + + sdata->u.ibss.channel = params->channel; ++ sdata->u.ibss.channel_type = params->channel_type; + sdata->u.ibss.fixed_channel = params->channel_fixed; + + /* fix ourselves to that channel now already */ + if (params->channel_fixed) { + sdata->local->oper_channel = params->channel; +- WARN_ON(!ieee80211_set_channel_type(sdata->local, sdata, +- NL80211_CHAN_NO_HT)); ++ if (!ieee80211_set_channel_type(sdata->local, sdata, ++ params->channel_type)) ++ return -EINVAL; + } + + if (params->ie) { +--- a/net/mac80211/ieee80211_i.h ++++ b/net/mac80211/ieee80211_i.h +@@ -470,6 +470,7 @@ struct ieee80211_if_ibss { + u8 ssid_len, ie_len; + u8 *ie; + struct ieee80211_channel *channel; ++ enum nl80211_channel_type channel_type; + + unsigned long ibss_join_req; + /* probe response/beacon for IBSS */ --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -178,7 +178,6 @@ static int ieee80211_do_open(struct net_ @@ -2171,7 +657,7 @@ u32 changed = 0; int res; u32 hw_reconf_flags = 0; -@@ -290,27 +289,6 @@ static int ieee80211_do_open(struct net_ +@@ -309,27 +308,6 @@ static int ieee80211_do_open(struct net_ set_bit(SDATA_STATE_RUNNING, &sdata->state); @@ -2184,8 +670,8 @@ - goto err_del_interface; - } - -- /* no locking required since STA is not live yet */ -- sta->flags |= WLAN_STA_AUTHORIZED; +- /* no atomic bitop required since STA is not live yet */ +- set_sta_flag(sta, WLAN_STA_AUTHORIZED); - - res = sta_info_insert(sta); - if (res) { @@ -2199,17 +685,17 @@ /* * set_multicast_list will be invoked by the networking core * which will check whether any increments here were done in -@@ -344,8 +322,7 @@ static int ieee80211_do_open(struct net_ +@@ -356,8 +334,7 @@ static int ieee80211_do_open(struct net_ netif_tx_start_all_queues(dev); return 0; - err_del_interface: -- drv_remove_interface(local, &sdata->vif); +- drv_remove_interface(local, sdata); + err_stop: if (!local->open_count) drv_stop(local); -@@ -718,6 +695,70 @@ static void ieee80211_if_setup(struct ne +@@ -732,6 +709,70 @@ static void ieee80211_if_setup(struct ne dev->destructor = free_netdev; } @@ -2266,10 +752,10 @@ + elems.ht_cap_elem, &sta->sta.ht_cap); + + if (elems.wmm_param) -+ set_sta_flags(sta, WLAN_STA_WME); ++ set_sta_flag(sta, WLAN_STA_WME); + + if (new) { -+ sta->flags = WLAN_STA_AUTHORIZED; ++ set_sta_flag(sta, WLAN_STA_AUTHORIZED); + rate_control_rate_init(sta); + sta_info_insert_rcu(sta); + } @@ -2280,7 +766,7 @@ static void ieee80211_iface_work(struct work_struct *work) { struct ieee80211_sub_if_data *sdata = -@@ -822,6 +863,9 @@ static void ieee80211_iface_work(struct +@@ -836,6 +877,9 @@ static void ieee80211_iface_work(struct break; ieee80211_mesh_rx_queued_mgmt(sdata, skb); break; @@ -2290,19 +776,85 @@ 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/rx.c +++ b/net/mac80211/rx.c -@@ -2163,7 +2163,8 @@ ieee80211_rx_h_action(struct ieee80211_r - */ +@@ -2250,7 +2250,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) break; /* verify action_code is present */ -@@ -2378,13 +2379,14 @@ ieee80211_rx_h_mgmt(struct ieee80211_rx_ +@@ -2465,13 +2467,14 @@ ieee80211_rx_h_mgmt(struct ieee80211_rx_ if (!ieee80211_vif_is_mesh(&sdata->vif) && sdata->vif.type != NL80211_IFTYPE_ADHOC && @@ -2319,7 +871,7 @@ break; case cpu_to_le16(IEEE80211_STYPE_DEAUTH): case cpu_to_le16(IEEE80211_STYPE_DISASSOC): -@@ -2727,10 +2729,16 @@ static int prepare_for_handlers(struct i +@@ -2818,10 +2821,16 @@ static int prepare_for_handlers(struct i } break; case NL80211_IFTYPE_WDS: @@ -2340,7 +892,7 @@ /* should never get here */ --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h -@@ -31,7 +31,6 @@ +@@ -32,7 +32,6 @@ * frames. * @WLAN_STA_ASSOC_AP: We're associated to that station, it is an AP. * @WLAN_STA_WME: Station is a QoS-STA. @@ -2348,515 +900,84 @@ * @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. -@@ -54,7 +53,6 @@ enum ieee80211_sta_info_flags { - WLAN_STA_SHORT_PREAMBLE = 1<<4, - WLAN_STA_ASSOC_AP = 1<<5, - WLAN_STA_WME = 1<<6, -- WLAN_STA_WDS = 1<<7, - WLAN_STA_CLEAR_PS_FILT = 1<<9, - WLAN_STA_MFP = 1<<10, - WLAN_STA_BLOCK_BA = 1<<11, ---- a/net/mac80211/status.c -+++ b/net/mac80211/status.c -@@ -278,17 +278,19 @@ void ieee80211_tx_status(struct ieee8021 - } - - if (!acked && ieee80211_is_back_req(fc)) { -+ u16 control; -+ - /* -- * BAR failed, let's tear down the BA session as a -- * last resort as some STAs (Intel 5100 on Windows) -- * can get stuck when the BA window isn't flushed -- * correctly. -+ * BAR failed, store the last SSN and retry sending -+ * the BAR when the next unicast transmission on the -+ * same TID succeeds. - */ - bar = (struct ieee80211_bar *) skb->data; -- if (!(bar->control & IEEE80211_BAR_CTRL_MULTI_TID)) { -+ control = le16_to_cpu(bar->control); -+ if (!(control & IEEE80211_BAR_CTRL_MULTI_TID)) { - u16 ssn = le16_to_cpu(bar->start_seq_num); - -- tid = (bar->control & -+ tid = (control & - IEEE80211_BAR_CTRL_TID_INFO_MASK) >> - IEEE80211_BAR_CTRL_TID_INFO_SHIFT; - ---- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c -+++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c -@@ -704,8 +704,10 @@ static void ar5008_hw_override_ini(struc - REG_WRITE(ah, AR_PCU_MISC_MODE2, val); - } - -- if (!AR_SREV_5416_20_OR_LATER(ah) || -- AR_SREV_9280_20_OR_LATER(ah)) -+ REG_SET_BIT(ah, AR_PHY_CCK_DETECT, -+ AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV); -+ -+ if (AR_SREV_9280_20_OR_LATER(ah)) - return; - /* - * Disable BB clock gating -@@ -802,7 +804,8 @@ static int ar5008_hw_process_ini(struct - - /* Write ADDAC shifts */ - REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_EXTERNAL_RADIO); -- ah->eep_ops->set_addac(ah, chan); -+ if (ah->eep_ops->set_addac) -+ ah->eep_ops->set_addac(ah, chan); - - if (AR_SREV_5416_22_OR_LATER(ah)) { - REG_WRITE_ARRAY(&ah->iniAddac, 1, regWrites); -@@ -1007,24 +1010,6 @@ static void ar5008_restore_chainmask(str - } - } - --static void ar5008_set_diversity(struct ath_hw *ah, bool value) --{ -- u32 v = REG_READ(ah, AR_PHY_CCK_DETECT); -- if (value) -- v |= AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV; -- else -- v &= ~AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV; -- REG_WRITE(ah, AR_PHY_CCK_DETECT, v); --} -- --static u32 ar9100_hw_compute_pll_control(struct ath_hw *ah, -- struct ath9k_channel *chan) --{ -- if (chan && IS_CHAN_5GHZ(chan)) -- return 0x1450; -- return 0x1458; --} -- - static u32 ar9160_hw_compute_pll_control(struct ath_hw *ah, - struct ath9k_channel *chan) - { -@@ -1654,7 +1639,6 @@ void ar5008_hw_attach_phy_ops(struct ath - priv_ops->rfbus_req = ar5008_hw_rfbus_req; - priv_ops->rfbus_done = ar5008_hw_rfbus_done; - priv_ops->restore_chainmask = ar5008_restore_chainmask; -- priv_ops->set_diversity = ar5008_set_diversity; - priv_ops->do_getnf = ar5008_hw_do_getnf; - priv_ops->set_radar_params = ar5008_hw_set_radar_params; - -@@ -1664,9 +1648,7 @@ void ar5008_hw_attach_phy_ops(struct ath - } else - priv_ops->ani_control = ar5008_hw_ani_control_old; - -- if (AR_SREV_9100(ah)) -- priv_ops->compute_pll_control = ar9100_hw_compute_pll_control; -- else if (AR_SREV_9160_10_OR_LATER(ah)) -+ if (AR_SREV_9100(ah) || AR_SREV_9160_10_OR_LATER(ah)) - priv_ops->compute_pll_control = ar9160_hw_compute_pll_control; - else - priv_ops->compute_pll_control = ar5008_hw_compute_pll_control; ---- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c -+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c -@@ -592,6 +592,9 @@ static void ar9003_hw_override_ini(struc - val = REG_READ(ah, AR_PCU_MISC_MODE2) & (~AR_ADHOC_MCAST_KEYID_ENABLE); - REG_WRITE(ah, AR_PCU_MISC_MODE2, - val | AR_AGG_WEP_ENABLE_FIX | AR_AGG_WEP_ENABLE); -+ -+ REG_SET_BIT(ah, AR_PHY_CCK_DETECT, -+ AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV); - } - - static void ar9003_hw_prog_ini(struct ath_hw *ah, -@@ -785,16 +788,6 @@ static void ar9003_hw_rfbus_done(struct - REG_WRITE(ah, AR_PHY_RFBUS_REQ, 0); - } - --static void ar9003_hw_set_diversity(struct ath_hw *ah, bool value) --{ -- u32 v = REG_READ(ah, AR_PHY_CCK_DETECT); -- if (value) -- v |= AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV; -- else -- v &= ~AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV; -- REG_WRITE(ah, AR_PHY_CCK_DETECT, v); --} -- - static bool ar9003_hw_ani_control(struct ath_hw *ah, - enum ath9k_ani_cmd cmd, int param) +@@ -62,7 +61,6 @@ enum ieee80211_sta_info_flags { + 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/wireless/chan.c ++++ b/net/wireless/chan.c +@@ -44,9 +44,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, ++ struct ieee80211_channel *chan, ++ enum nl80211_channel_type channel_type) { -@@ -1277,7 +1270,6 @@ void ar9003_hw_attach_phy_ops(struct ath - priv_ops->set_delta_slope = ar9003_hw_set_delta_slope; - priv_ops->rfbus_req = ar9003_hw_rfbus_req; - priv_ops->rfbus_done = ar9003_hw_rfbus_done; -- priv_ops->set_diversity = ar9003_hw_set_diversity; - priv_ops->ani_control = ar9003_hw_ani_control; - priv_ops->do_getnf = ar9003_hw_do_getnf; - priv_ops->ani_cache_ini_regs = ar9003_hw_ani_cache_ini_regs; ---- a/drivers/net/wireless/ath/ath9k/eeprom.c -+++ b/drivers/net/wireless/ath/ath9k/eeprom.c -@@ -456,12 +456,7 @@ void ath9k_hw_get_gain_boundaries_pdadcs - pPdGainBoundaries[i] = - min((u16)MAX_RATE_POWER, pPdGainBoundaries[i]); - -- if ((i == 0) && !AR_SREV_5416_20_OR_LATER(ah)) { -- minDelta = pPdGainBoundaries[0] - 23; -- pPdGainBoundaries[0] = 23; -- } else { -- minDelta = 0; -- } -+ minDelta = 0; - - if (i == 0) { - if (AR_SREV_9280_20_OR_LATER(ah)) ---- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c -+++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c -@@ -405,12 +405,7 @@ static void ath9k_hw_set_4k_power_cal_ta - REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_3, 0); - - for (i = 0; i < AR5416_EEP4K_MAX_CHAINS; i++) { -- if (AR_SREV_5416_20_OR_LATER(ah) && -- (ah->rxchainmask == 5 || ah->txchainmask == 5) && -- (i != 0)) { -- regChainOffset = (i == 1) ? 0x2000 : 0x1000; -- } else -- regChainOffset = i * 0x1000; -+ regChainOffset = i * 0x1000; - - if (pEepData->baseEepHeader.txMask & (1 << i)) { - pRawDataset = pEepData->calPierData2G[i]; -@@ -423,19 +418,17 @@ static void ath9k_hw_set_4k_power_cal_ta - - ENABLE_REGWRITE_BUFFER(ah); - -- if ((i == 0) || AR_SREV_5416_20_OR_LATER(ah)) { -- REG_WRITE(ah, AR_PHY_TPCRG5 + regChainOffset, -- SM(pdGainOverlap_t2, -- AR_PHY_TPCRG5_PD_GAIN_OVERLAP) -- | SM(gainBoundaries[0], -- AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1) -- | SM(gainBoundaries[1], -- AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2) -- | SM(gainBoundaries[2], -- AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3) -- | SM(gainBoundaries[3], -- AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4)); -- } -+ REG_WRITE(ah, AR_PHY_TPCRG5 + regChainOffset, -+ SM(pdGainOverlap_t2, -+ AR_PHY_TPCRG5_PD_GAIN_OVERLAP) -+ | SM(gainBoundaries[0], -+ AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1) -+ | SM(gainBoundaries[1], -+ AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2) -+ | SM(gainBoundaries[2], -+ AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3) -+ | SM(gainBoundaries[3], -+ AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4)); - - regOffset = AR_PHY_BASE + (672 << 2) + regChainOffset; - for (j = 0; j < 32; j++) { -@@ -715,10 +708,8 @@ static void ath9k_hw_4k_set_txpower(stru - if (test) - return; - -- if (AR_SREV_9280_20_OR_LATER(ah)) { -- for (i = 0; i < Ar5416RateSize; i++) -- ratesArray[i] -= AR5416_PWR_TABLE_OFFSET_DB * 2; -- } -+ for (i = 0; i < Ar5416RateSize; i++) -+ ratesArray[i] -= AR5416_PWR_TABLE_OFFSET_DB * 2; + struct ieee80211_channel *sec_chan; + int diff; +@@ -75,6 +75,7 @@ static bool can_beacon_sec_chan(struct w - ENABLE_REGWRITE_BUFFER(ah); - -@@ -788,28 +779,6 @@ static void ath9k_hw_4k_set_txpower(stru - REGWRITE_BUFFER_FLUSH(ah); + return true; } - --static void ath9k_hw_4k_set_addac(struct ath_hw *ah, -- struct ath9k_channel *chan) --{ -- struct modal_eep_4k_header *pModal; -- struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k; -- u8 biaslevel; -- -- if (ah->hw_version.macVersion != AR_SREV_VERSION_9160) -- return; -- -- if (ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_MINOR_VER_7) -- return; -- -- pModal = &eep->modalHeader; -- -- if (pModal->xpaBiasLvl != 0xff) { -- biaslevel = pModal->xpaBiasLvl; -- INI_RA(&ah->iniAddac, 7, 1) = -- (INI_RA(&ah->iniAddac, 7, 1) & (~0x18)) | biaslevel << 3; -- } --} -- - static void ath9k_hw_4k_set_gain(struct ath_hw *ah, - struct modal_eep_4k_header *pModal, - struct ar5416_eeprom_4k *eep, -@@ -877,6 +846,7 @@ static void ath9k_hw_4k_set_board_values - u8 txRxAttenLocal; - u8 ob[5], db1[5], db2[5]; - u8 ant_div_control1, ant_div_control2; -+ u8 bb_desired_scale; - u32 regVal; - - pModal = &eep->modalHeader; -@@ -1096,30 +1066,29 @@ static void ath9k_hw_4k_set_board_values - AR_PHY_SETTLING_SWITCH, - pModal->swSettleHt40); ++EXPORT_SYMBOL(cfg80211_can_beacon_sec_chan); + + 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 + switch (channel_type) { + case NL80211_CHAN_HT40PLUS: + case NL80211_CHAN_HT40MINUS: +- if (!can_beacon_sec_chan(&rdev->wiphy, chan, +- channel_type)) { ++ if (!cfg80211_can_beacon_sec_chan(&rdev->wiphy, chan, ++ channel_type)) { + printk(KERN_DEBUG + "cfg80211: Secondary channel not " + "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 + ibss.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]); } -- if (AR_SREV_9271(ah) || AR_SREV_9285(ah)) { -- u8 bb_desired_scale = (pModal->bb_scale_smrt_antenna & -- EEP_4K_BB_DESIRED_SCALE_MASK); -- if ((pBase->txGainType == 0) && (bb_desired_scale != 0)) { -- u32 pwrctrl, mask, clr; -- -- mask = BIT(0)|BIT(5)|BIT(10)|BIT(15)|BIT(20)|BIT(25); -- pwrctrl = mask * bb_desired_scale; -- clr = mask * 0x1f; -- REG_RMW(ah, AR_PHY_TX_PWRCTRL8, pwrctrl, clr); -- REG_RMW(ah, AR_PHY_TX_PWRCTRL10, pwrctrl, clr); -- REG_RMW(ah, AR_PHY_CH0_TX_PWRCTRL12, pwrctrl, clr); -- -- mask = BIT(0)|BIT(5)|BIT(15); -- pwrctrl = mask * bb_desired_scale; -- clr = mask * 0x1f; -- REG_RMW(ah, AR_PHY_TX_PWRCTRL9, pwrctrl, clr); -- -- mask = BIT(0)|BIT(5); -- pwrctrl = mask * bb_desired_scale; -- clr = mask * 0x1f; -- REG_RMW(ah, AR_PHY_CH0_TX_PWRCTRL11, pwrctrl, clr); -- REG_RMW(ah, AR_PHY_CH0_TX_PWRCTRL13, pwrctrl, clr); -- } -+ -+ bb_desired_scale = (pModal->bb_scale_smrt_antenna & -+ EEP_4K_BB_DESIRED_SCALE_MASK); -+ if ((pBase->txGainType == 0) && (bb_desired_scale != 0)) { -+ u32 pwrctrl, mask, clr; -+ -+ mask = BIT(0)|BIT(5)|BIT(10)|BIT(15)|BIT(20)|BIT(25); -+ pwrctrl = mask * bb_desired_scale; -+ clr = mask * 0x1f; -+ REG_RMW(ah, AR_PHY_TX_PWRCTRL8, pwrctrl, clr); -+ REG_RMW(ah, AR_PHY_TX_PWRCTRL10, pwrctrl, clr); -+ REG_RMW(ah, AR_PHY_CH0_TX_PWRCTRL12, pwrctrl, clr); + +- ibss.channel = ieee80211_get_channel(wiphy, +- nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ])); ++ if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) { ++ enum nl80211_channel_type channel_type; + -+ mask = BIT(0)|BIT(5)|BIT(15); -+ pwrctrl = mask * bb_desired_scale; -+ clr = mask * 0x1f; -+ REG_RMW(ah, AR_PHY_TX_PWRCTRL9, pwrctrl, clr); ++ channel_type = nla_get_u32( ++ info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]); ++ if (channel_type > NL80211_CHAN_HT40PLUS) ++ return -EINVAL; ++ ibss.channel_type = channel_type; ++ } else { ++ ibss.channel_type = NL80211_CHAN_NO_HT; ++ } + -+ mask = BIT(0)|BIT(5); -+ pwrctrl = mask * bb_desired_scale; -+ clr = mask * 0x1f; -+ REG_RMW(ah, AR_PHY_CH0_TX_PWRCTRL11, pwrctrl, clr); -+ REG_RMW(ah, AR_PHY_CH0_TX_PWRCTRL13, pwrctrl, clr); - } - } - -@@ -1161,7 +1130,6 @@ const struct eeprom_ops eep_4k_ops = { - .get_eeprom_ver = ath9k_hw_4k_get_eeprom_ver, - .get_eeprom_rev = ath9k_hw_4k_get_eeprom_rev, - .set_board_values = ath9k_hw_4k_set_board_values, -- .set_addac = ath9k_hw_4k_set_addac, - .set_txpower = ath9k_hw_4k_set_txpower, - .get_spur_channel = ath9k_hw_4k_get_spur_channel - }; ---- a/drivers/net/wireless/ath/ath9k/eeprom_9287.c -+++ b/drivers/net/wireless/ath/ath9k/eeprom_9287.c -@@ -851,10 +851,8 @@ static void ath9k_hw_ar9287_set_txpower( - if (test) - return; - -- if (AR_SREV_9280_20_OR_LATER(ah)) { -- for (i = 0; i < Ar5416RateSize; i++) -- ratesArray[i] -= AR9287_PWR_TABLE_OFFSET_DB * 2; -- } -+ for (i = 0; i < Ar5416RateSize; i++) -+ ratesArray[i] -= AR9287_PWR_TABLE_OFFSET_DB * 2; - - ENABLE_REGWRITE_BUFFER(ah); - -@@ -944,11 +942,6 @@ static void ath9k_hw_ar9287_set_txpower( - REGWRITE_BUFFER_FLUSH(ah); - } - --static void ath9k_hw_ar9287_set_addac(struct ath_hw *ah, -- struct ath9k_channel *chan) --{ --} -- - static void ath9k_hw_ar9287_set_board_values(struct ath_hw *ah, - struct ath9k_channel *chan) - { -@@ -1100,7 +1093,6 @@ const struct eeprom_ops eep_ar9287_ops = - .get_eeprom_ver = ath9k_hw_ar9287_get_eeprom_ver, - .get_eeprom_rev = ath9k_hw_ar9287_get_eeprom_rev, - .set_board_values = ath9k_hw_ar9287_set_board_values, -- .set_addac = ath9k_hw_ar9287_set_addac, - .set_txpower = ath9k_hw_ar9287_set_txpower, - .get_spur_channel = ath9k_hw_ar9287_get_spur_channel - }; ---- a/drivers/net/wireless/ath/ath9k/eeprom_def.c -+++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c -@@ -547,8 +547,7 @@ static void ath9k_hw_def_set_board_value - break; - } - -- if (AR_SREV_5416_20_OR_LATER(ah) && -- (ah->rxchainmask == 5 || ah->txchainmask == 5) && (i != 0)) -+ if ((ah->rxchainmask == 5 || ah->txchainmask == 5) && (i != 0)) - regChainOffset = (i == 1) ? 0x2000 : 0x1000; - else - regChainOffset = i * 0x1000; -@@ -565,9 +564,8 @@ static void ath9k_hw_def_set_board_value - SM(pModal->iqCalQCh[i], - AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF)); - -- if ((i == 0) || AR_SREV_5416_20_OR_LATER(ah)) -- ath9k_hw_def_set_gain(ah, pModal, eep, txRxAttenLocal, -- regChainOffset, i); -+ ath9k_hw_def_set_gain(ah, pModal, eep, txRxAttenLocal, -+ regChainOffset, i); - } - - if (AR_SREV_9280_20_OR_LATER(ah)) { -@@ -893,8 +891,7 @@ static void ath9k_hw_set_def_power_cal_t - xpdGainValues[2]); - - for (i = 0; i < AR5416_MAX_CHAINS; i++) { -- if (AR_SREV_5416_20_OR_LATER(ah) && -- (ah->rxchainmask == 5 || ah->txchainmask == 5) && -+ if ((ah->rxchainmask == 5 || ah->txchainmask == 5) && - (i != 0)) { - regChainOffset = (i == 1) ? 0x2000 : 0x1000; - } else -@@ -935,27 +932,24 @@ static void ath9k_hw_set_def_power_cal_t - - ENABLE_REGWRITE_BUFFER(ah); - -- if ((i == 0) || AR_SREV_5416_20_OR_LATER(ah)) { -- if (OLC_FOR_AR9280_20_LATER) { -- REG_WRITE(ah, -- AR_PHY_TPCRG5 + regChainOffset, -- SM(0x6, -- AR_PHY_TPCRG5_PD_GAIN_OVERLAP) | -- SM_PD_GAIN(1) | SM_PD_GAIN(2) | -- SM_PD_GAIN(3) | SM_PD_GAIN(4)); -- } else { -- REG_WRITE(ah, -- AR_PHY_TPCRG5 + regChainOffset, -- SM(pdGainOverlap_t2, -- AR_PHY_TPCRG5_PD_GAIN_OVERLAP)| -- SM_PDGAIN_B(0, 1) | -- SM_PDGAIN_B(1, 2) | -- SM_PDGAIN_B(2, 3) | -- SM_PDGAIN_B(3, 4)); -- } -+ if (OLC_FOR_AR9280_20_LATER) { -+ REG_WRITE(ah, -+ AR_PHY_TPCRG5 + regChainOffset, -+ SM(0x6, -+ AR_PHY_TPCRG5_PD_GAIN_OVERLAP) | -+ SM_PD_GAIN(1) | SM_PD_GAIN(2) | -+ SM_PD_GAIN(3) | SM_PD_GAIN(4)); -+ } else { -+ REG_WRITE(ah, -+ AR_PHY_TPCRG5 + regChainOffset, -+ SM(pdGainOverlap_t2, -+ AR_PHY_TPCRG5_PD_GAIN_OVERLAP)| -+ SM_PDGAIN_B(0, 1) | -+ SM_PDGAIN_B(1, 2) | -+ SM_PDGAIN_B(2, 3) | -+ SM_PDGAIN_B(3, 4)); - } - -- - ath9k_adjust_pdadc_values(ah, pwr_table_offset, - diff, pdadcValues); - ---- a/drivers/net/wireless/ath/ath9k/init.c -+++ b/drivers/net/wireless/ath/ath9k/init.c -@@ -506,7 +506,6 @@ static void ath9k_init_misc(struct ath_s - sc->sc_flags |= SC_OP_RXAGGR; - } - -- ath9k_hw_set_diversity(sc->sc_ah, true); - sc->rx.defant = ath9k_hw_getdefantenna(sc->sc_ah); - - memcpy(common->bssidmask, ath_bcast_mac, ETH_ALEN); ---- a/drivers/net/wireless/ath/ath9k/reg.h -+++ b/drivers/net/wireless/ath/ath9k/reg.h -@@ -800,10 +800,6 @@ - #define AR_SREV_5416(_ah) \ - (((_ah)->hw_version.macVersion == AR_SREV_VERSION_5416_PCI) || \ - ((_ah)->hw_version.macVersion == AR_SREV_VERSION_5416_PCIE)) --#define AR_SREV_5416_20_OR_LATER(_ah) \ -- (((AR_SREV_5416(_ah)) && \ -- ((_ah)->hw_version.macRev >= AR_SREV_REVISION_5416_20)) || \ -- ((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9100)) - #define AR_SREV_5416_22_OR_LATER(_ah) \ - (((AR_SREV_5416(_ah)) && \ - ((_ah)->hw_version.macRev >= AR_SREV_REVISION_5416_22)) || \ ---- a/drivers/net/wireless/ath/ath9k/ar9002_calib.c -+++ b/drivers/net/wireless/ath/ath9k/ar9002_calib.c -@@ -869,6 +869,7 @@ static bool ar9002_hw_init_cal(struct at - ar9002_hw_pa_cal(ah, true); - - /* Do NF Calibration after DC offset and other calibrations */ -+ ath9k_hw_loadnf(ah, chan); - ath9k_hw_start_nfcal(ah, true); - - if (ah->caldata) ---- a/net/mac80211/ieee80211_i.h -+++ b/net/mac80211/ieee80211_i.h -@@ -671,7 +671,6 @@ enum queue_stop_reason { - IEEE80211_QUEUE_STOP_REASON_AGGREGATION, - IEEE80211_QUEUE_STOP_REASON_SUSPEND, - IEEE80211_QUEUE_STOP_REASON_SKB_ADD, -- IEEE80211_QUEUE_STOP_REASON_CHTYPE_CHANGE, - }; - - #ifdef CONFIG_MAC80211_LEDS ---- a/net/mac80211/mlme.c -+++ b/net/mac80211/mlme.c -@@ -1921,24 +1921,8 @@ static void ieee80211_rx_mgmt_beacon(str - - rcu_read_unlock(); - -- /* -- * Whenever the AP announces the HT mode change that can be -- * 40MHz intolerant or etc., it would be safer to stop tx -- * queues before doing hw config to avoid buffer overflow. -- */ -- ieee80211_stop_queues_by_reason(&sdata->local->hw, -- IEEE80211_QUEUE_STOP_REASON_CHTYPE_CHANGE); -- -- /* flush out all packets */ -- synchronize_net(); -- -- drv_flush(local, false); -- - changed |= ieee80211_enable_ht(sdata, elems.ht_info_elem, - bssid, ap_ht_cap_flags); -- -- ieee80211_wake_queues_by_reason(&sdata->local->hw, -- IEEE80211_QUEUE_STOP_REASON_CHTYPE_CHANGE); - } - - /* Note: country IE parsing is done for us by cfg80211 */ ---- a/drivers/net/wireless/b43/main.c -+++ b/drivers/net/wireless/b43/main.c -@@ -1613,7 +1613,8 @@ static void handle_irq_beacon(struct b43 - u32 cmd, beacon0_valid, beacon1_valid; ++ ibss.channel = rdev_freq_to_chan(rdev, ++ 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; - if (!b43_is_mode(wl, NL80211_IFTYPE_AP) && -- !b43_is_mode(wl, NL80211_IFTYPE_MESH_POINT)) -+ !b43_is_mode(wl, NL80211_IFTYPE_MESH_POINT) && -+ !b43_is_mode(wl, NL80211_IFTYPE_ADHOC)) - return; ++ /* Both channels should be able to initiate communication */ ++ if ((ibss.channel_type == NL80211_CHAN_HT40PLUS || ++ ibss.channel_type == NL80211_CHAN_HT40MINUS) && ++ !cfg80211_can_beacon_sec_chan(&rdev->wiphy, ibss.channel, ++ ibss.channel_type)) ++ return -EINVAL; ++ + ibss.channel_fixed = !!info->attrs[NL80211_ATTR_FREQ_FIXED]; + ibss.privacy = !!info->attrs[NL80211_ATTR_PRIVACY]; - /* This is the bottom half of the asynchronous beacon update. */ diff --git a/package/mac80211/patches/310-ibss_ht.patch b/package/mac80211/patches/310-ibss_ht.patch deleted file mode 100644 index 6e0de5b467..0000000000 --- a/package/mac80211/patches/310-ibss_ht.patch +++ /dev/null @@ -1,720 +0,0 @@ ---- a/include/net/cfg80211.h -+++ b/include/net/cfg80211.h -@@ -1101,6 +1101,7 @@ struct cfg80211_ibss_params { - u8 *ssid; - u8 *bssid; - struct ieee80211_channel *channel; -+ enum nl80211_channel_type channel_type; - u8 *ie; - u8 ssid_len, ie_len; - u16 beacon_interval; -@@ -2612,6 +2613,12 @@ struct cfg80211_bss *cfg80211_get_bss(st - const u8 *bssid, - const u8 *ssid, size_t ssid_len, - u16 capa_mask, u16 capa_val); -+struct cfg80211_bss *cfg80211_get_bss_ht(struct wiphy *wiphy, -+ struct ieee80211_channel *channel, -+ const u8 *bssid, -+ const u8 *ssid, size_t ssid_len, -+ u16 capa_mask, u16 capa_val, -+ enum nl80211_channel_type channel_type); - static inline struct cfg80211_bss * - cfg80211_get_ibss(struct wiphy *wiphy, - struct ieee80211_channel *channel, ---- a/net/wireless/nl80211.c -+++ b/net/wireless/nl80211.c -@@ -4539,13 +4539,41 @@ static int nl80211_join_ibss(struct sk_b - ibss.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]); - } - -- ibss.channel = ieee80211_get_channel(wiphy, -- nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ])); -+ if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) { -+ enum nl80211_channel_type channel_type; -+ -+ channel_type = nla_get_u32( -+ info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]); -+ if (channel_type != NL80211_CHAN_NO_HT && -+ channel_type != NL80211_CHAN_HT20 && -+ channel_type != NL80211_CHAN_HT40PLUS && -+ channel_type != NL80211_CHAN_HT40MINUS) -+ return -EINVAL; -+ ibss.channel_type = channel_type; -+ } else { -+ ibss.channel_type = NL80211_CHAN_NO_HT; -+ } -+ -+ ibss.channel = rdev_freq_to_chan(rdev, -+ nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]), -+ ibss.channel_type); - if (!ibss.channel || -+ ibss.channel->flags & IEEE80211_CHAN_PASSIVE_SCAN || - ibss.channel->flags & IEEE80211_CHAN_NO_IBSS || -- ibss.channel->flags & IEEE80211_CHAN_DISABLED) -+ ibss.channel->flags & IEEE80211_CHAN_RADAR) - return -EINVAL; - -+ /* Both channels should be able to initiate communication */ -+ if ((ibss.channel_type == NL80211_CHAN_HT40PLUS || -+ ibss.channel_type == NL80211_CHAN_HT40MINUS) && -+ !can_beacon_sec_chan(&rdev->wiphy, ibss.channel, -+ ibss.channel_type)) { -+ printk(KERN_DEBUG -+ "cfg80211: Secondary channel not " -+ "allowed to initiate communication\n"); -+ return -EINVAL; -+ } -+ - ibss.channel_fixed = !!info->attrs[NL80211_ATTR_FREQ_FIXED]; - ibss.privacy = !!info->attrs[NL80211_ATTR_PRIVACY]; - ---- a/net/wireless/chan.c -+++ b/net/wireless/chan.c -@@ -44,7 +44,7 @@ rdev_freq_to_chan(struct cfg80211_regist - return chan; - } - --static bool can_beacon_sec_chan(struct wiphy *wiphy, -+bool can_beacon_sec_chan(struct wiphy *wiphy, - struct ieee80211_channel *chan, - enum nl80211_channel_type channel_type) - { -@@ -75,6 +75,7 @@ static bool can_beacon_sec_chan(struct w - - return true; - } -+EXPORT_SYMBOL(can_beacon_sec_chan); - - int cfg80211_set_freq(struct cfg80211_registered_device *rdev, - struct wireless_dev *wdev, int freq, ---- a/net/wireless/core.h -+++ b/net/wireless/core.h -@@ -439,6 +439,9 @@ cfg80211_can_add_interface(struct cfg802 - struct ieee80211_channel * - rdev_freq_to_chan(struct cfg80211_registered_device *rdev, - int freq, enum nl80211_channel_type channel_type); -+bool can_beacon_sec_chan(struct wiphy *wiphy, -+ struct ieee80211_channel *chan, -+ enum nl80211_channel_type channel_type); - int cfg80211_set_freq(struct cfg80211_registered_device *rdev, - struct wireless_dev *wdev, int freq, - enum nl80211_channel_type channel_type); ---- a/net/wireless/scan.c -+++ b/net/wireless/scan.c -@@ -365,6 +365,19 @@ struct cfg80211_bss *cfg80211_get_bss(st - const u8 *ssid, size_t ssid_len, - u16 capa_mask, u16 capa_val) - { -+ /* call HT version with no HT requirements */ -+ return cfg80211_get_bss_ht(wiphy, channel, bssid, ssid, ssid_len, -+ capa_mask, capa_val, NL80211_CHAN_NO_HT); -+} -+EXPORT_SYMBOL(cfg80211_get_bss); -+ -+struct cfg80211_bss *cfg80211_get_bss_ht(struct wiphy *wiphy, -+ struct ieee80211_channel *channel, -+ const u8 *bssid, -+ const u8 *ssid, size_t ssid_len, -+ u16 capa_mask, u16 capa_val, -+ enum nl80211_channel_type require_ht) -+{ - struct cfg80211_registered_device *dev = wiphy_to_dev(wiphy); - struct cfg80211_internal_bss *bss, *res = NULL; - unsigned long now = jiffies; -@@ -374,8 +387,26 @@ struct cfg80211_bss *cfg80211_get_bss(st - list_for_each_entry(bss, &dev->bss_list, list) { - if ((bss->pub.capability & capa_mask) != capa_val) - continue; -- if (channel && bss->pub.channel != channel) -- continue; -+ if (channel) { -+ if (bss->pub.channel != channel) -+ continue; -+ if (require_ht != NL80211_CHAN_NO_HT) { -+ struct ieee80211_ht_info *ht_info; -+ ht_info = (struct ieee80211_ht_info *) -+ ieee80211_bss_get_ie(&bss->pub, -+ WLAN_EID_HT_INFORMATION); -+ if (!ht_info) -+ continue; -+ if (require_ht == NL80211_CHAN_HT40MINUS && -+ !(ht_info->ht_param & -+ IEEE80211_HT_PARAM_CHA_SEC_BELOW)) -+ continue; -+ if (require_ht == NL80211_CHAN_HT40PLUS && -+ !(ht_info->ht_param & -+ IEEE80211_HT_PARAM_CHA_SEC_ABOVE)) -+ continue; -+ } -+ } - /* Don't get expired BSS structs */ - if (time_after(now, bss->ts + IEEE80211_SCAN_RESULT_EXPIRE) && - !atomic_read(&bss->hold)) -@@ -392,7 +423,7 @@ struct cfg80211_bss *cfg80211_get_bss(st - return NULL; - return &res->pub; - } --EXPORT_SYMBOL(cfg80211_get_bss); -+EXPORT_SYMBOL(cfg80211_get_bss_ht); - - struct cfg80211_bss *cfg80211_get_mesh(struct wiphy *wiphy, - struct ieee80211_channel *channel, ---- a/net/mac80211/ieee80211_i.h -+++ b/net/mac80211/ieee80211_i.h -@@ -465,6 +465,7 @@ struct ieee80211_if_ibss { - u8 ssid_len, ie_len; - u8 *ie; - struct ieee80211_channel *channel; -+ enum nl80211_channel_type channel_type; - - unsigned long ibss_join_req; - /* probe response/beacon for IBSS */ -@@ -1090,6 +1091,7 @@ void ieee80211_ibss_notify_scan_complete - void ieee80211_ibss_setup_sdata(struct ieee80211_sub_if_data *sdata); - struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata, - u8 *bssid, u8 *addr, u32 supp_rates, -+ struct ieee80211_ht_cap *ht_cap, - gfp_t gfp); - int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata, - struct cfg80211_ibss_params *params); -@@ -1343,6 +1345,12 @@ void ieee80211_recalc_smps(struct ieee80 - size_t ieee80211_ie_split(const u8 *ies, size_t ielen, - const u8 *ids, int n_ids, size_t offset); - size_t ieee80211_ie_split_vendor(const u8 *ies, size_t ielen, size_t offset); -+u8 *ieee80211_ie_build_ht_cap(u8 *pos, struct ieee80211_supported_band *sband, -+ u16 cap); -+u8 *ieee80211_ie_build_ht_info(u8 *pos, -+ struct ieee80211_sta_ht_cap *ht_cap, -+ struct ieee80211_channel *channel, -+ enum nl80211_channel_type channel_type); - - /* internal work items */ - void ieee80211_work_init(struct ieee80211_local *local); -@@ -1371,6 +1379,8 @@ ieee80211_get_channel_mode(struct ieee80 - bool ieee80211_set_channel_type(struct ieee80211_local *local, - struct ieee80211_sub_if_data *sdata, - enum nl80211_channel_type chantype); -+enum nl80211_channel_type ieee80211_ht_info_to_channel_type( -+ struct ieee80211_ht_info *ht_info); - - #ifdef CONFIG_MAC80211_NOINLINE - #define debug_noinline noinline ---- a/net/mac80211/util.c -+++ b/net/mac80211/util.c -@@ -839,23 +839,8 @@ int ieee80211_build_preq_ies(struct ieee - offset = noffset; - } - -- if (sband->ht_cap.ht_supported) { -- u16 cap = sband->ht_cap.cap; -- __le16 tmp; -- -- *pos++ = WLAN_EID_HT_CAPABILITY; -- *pos++ = sizeof(struct ieee80211_ht_cap); -- memset(pos, 0, sizeof(struct ieee80211_ht_cap)); -- tmp = cpu_to_le16(cap); -- memcpy(pos, &tmp, sizeof(u16)); -- pos += sizeof(u16); -- *pos++ = sband->ht_cap.ampdu_factor | -- (sband->ht_cap.ampdu_density << -- IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT); -- memcpy(pos, &sband->ht_cap.mcs, sizeof(sband->ht_cap.mcs)); -- pos += sizeof(sband->ht_cap.mcs); -- pos += 2 + 4 + 1; /* ext info, BF cap, antsel */ -- } -+ if (sband->ht_cap.ht_supported) -+ pos = ieee80211_ie_build_ht_cap(pos, sband, sband->ht_cap.cap); - - /* - * If adding more here, adjust code in main.c -@@ -1378,3 +1363,100 @@ void ieee80211_disable_rssi_reports(stru - _ieee80211_enable_rssi_reports(sdata, 0, 0); - } - EXPORT_SYMBOL(ieee80211_disable_rssi_reports); -+ -+u8 *ieee80211_ie_build_ht_cap(u8 *pos, struct ieee80211_supported_band *sband, -+ u16 cap) -+{ -+ __le16 tmp; -+ -+ *pos++ = WLAN_EID_HT_CAPABILITY; -+ *pos++ = sizeof(struct ieee80211_ht_cap); -+ memset(pos, 0, sizeof(struct ieee80211_ht_cap)); -+ -+ /* capability flags */ -+ tmp = cpu_to_le16(cap); -+ memcpy(pos, &tmp, sizeof(u16)); -+ pos += sizeof(u16); -+ -+ /* AMPDU parameters */ -+ *pos++ = sband->ht_cap.ampdu_factor | -+ (sband->ht_cap.ampdu_density << -+ IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT); -+ -+ /* MCS set */ -+ memcpy(pos, &sband->ht_cap.mcs, sizeof(sband->ht_cap.mcs)); -+ pos += sizeof(sband->ht_cap.mcs); -+ -+ /* extended capabilities */ -+ pos += sizeof(__le16); -+ -+ /* BF capabilities */ -+ pos += sizeof(__le32); -+ -+ /* antenna selection */ -+ pos += sizeof(u8); -+ -+ return pos; -+} -+ -+u8 *ieee80211_ie_build_ht_info(u8 *pos, -+ struct ieee80211_sta_ht_cap *ht_cap, -+ struct ieee80211_channel *channel, -+ enum nl80211_channel_type channel_type) -+{ -+ struct ieee80211_ht_info *ht_info; -+ /* Build HT Information */ -+ *pos++ = WLAN_EID_HT_INFORMATION; -+ *pos++ = sizeof(struct ieee80211_ht_info); -+ ht_info = (struct ieee80211_ht_info *)pos; -+ ht_info->control_chan = -+ ieee80211_frequency_to_channel(channel->center_freq); -+ switch (channel_type) { -+ case NL80211_CHAN_HT40MINUS: -+ ht_info->ht_param = IEEE80211_HT_PARAM_CHA_SEC_BELOW; -+ break; -+ case NL80211_CHAN_HT40PLUS: -+ ht_info->ht_param = IEEE80211_HT_PARAM_CHA_SEC_ABOVE; -+ break; -+ case NL80211_CHAN_HT20: -+ default: -+ ht_info->ht_param = IEEE80211_HT_PARAM_CHA_SEC_NONE; -+ break; -+ } -+ if (ht_cap->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) -+ ht_info->ht_param |= IEEE80211_HT_PARAM_CHAN_WIDTH_ANY; -+ ht_info->operation_mode = 0x0000; -+ ht_info->stbc_param = 0x0000; -+ -+ /* It seems that Basic MCS set and Supported MCS set -+ are identical for the first 10 bytes */ -+ memset(&ht_info->basic_set, 0, 16); -+ memcpy(&ht_info->basic_set, &ht_cap->mcs, 10); -+ -+ return pos + sizeof(struct ieee80211_ht_info); -+} -+ -+enum nl80211_channel_type ieee80211_ht_info_to_channel_type( -+ struct ieee80211_ht_info *ht_info) -+{ -+ enum nl80211_channel_type channel_type; -+ -+ if (!ht_info) -+ return NL80211_CHAN_NO_HT; -+ -+ switch (ht_info->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) { -+ case IEEE80211_HT_PARAM_CHA_SEC_NONE: -+ channel_type = NL80211_CHAN_HT20; -+ break; -+ case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: -+ channel_type = NL80211_CHAN_HT40PLUS; -+ break; -+ case IEEE80211_HT_PARAM_CHA_SEC_BELOW: -+ channel_type = NL80211_CHAN_HT40MINUS; -+ break; -+ default: -+ channel_type = NL80211_CHAN_NO_HT; -+ } -+ -+ return channel_type; -+} ---- a/net/mac80211/work.c -+++ b/net/mac80211/work.c -@@ -118,7 +118,6 @@ static void ieee80211_add_ht_ie(struct s - u8 *pos; - u32 flags = channel->flags; - u16 cap = sband->ht_cap.cap; -- __le16 tmp; - - if (!sband->ht_cap.ht_supported) - return; -@@ -169,34 +168,8 @@ static void ieee80211_add_ht_ie(struct s - } - - /* reserve and fill IE */ -- - pos = skb_put(skb, sizeof(struct ieee80211_ht_cap) + 2); -- *pos++ = WLAN_EID_HT_CAPABILITY; -- *pos++ = sizeof(struct ieee80211_ht_cap); -- memset(pos, 0, sizeof(struct ieee80211_ht_cap)); -- -- /* capability flags */ -- tmp = cpu_to_le16(cap); -- memcpy(pos, &tmp, sizeof(u16)); -- pos += sizeof(u16); -- -- /* AMPDU parameters */ -- *pos++ = sband->ht_cap.ampdu_factor | -- (sband->ht_cap.ampdu_density << -- IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT); -- -- /* MCS set */ -- memcpy(pos, &sband->ht_cap.mcs, sizeof(sband->ht_cap.mcs)); -- pos += sizeof(sband->ht_cap.mcs); -- -- /* extended capabilities */ -- pos += sizeof(__le16); -- -- /* BF capabilities */ -- pos += sizeof(__le32); -- -- /* antenna selection */ -- pos += sizeof(u8); -+ ieee80211_ie_build_ht_cap(pos, sband, cap); - } - - static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata, ---- a/net/mac80211/agg-tx.c -+++ b/net/mac80211/agg-tx.c -@@ -82,6 +82,8 @@ static void ieee80211_send_addba_request - 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_ADHOC) -+ memcpy(mgmt->bssid, sdata->u.ibss.bssid, ETH_ALEN); - - mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | - IEEE80211_STYPE_ACTION); -@@ -399,7 +401,8 @@ int ieee80211_start_tx_ba_session(struct - if (sdata->vif.type != NL80211_IFTYPE_STATION && - sdata->vif.type != NL80211_IFTYPE_AP_VLAN && - sdata->vif.type != NL80211_IFTYPE_AP && -- sdata->vif.type != NL80211_IFTYPE_WDS) -+ sdata->vif.type != NL80211_IFTYPE_WDS && -+ sdata->vif.type != NL80211_IFTYPE_ADHOC) - return -EINVAL; - - if (test_sta_flags(sta, WLAN_STA_BLOCK_BA)) { ---- a/net/mac80211/ht.c -+++ b/net/mac80211/ht.c -@@ -199,6 +199,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); -+ else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) -+ memcpy(mgmt->bssid, sdata->u.ibss.bssid, ETH_ALEN); - - mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | - IEEE80211_STYPE_ACTION); ---- a/net/mac80211/ibss.c -+++ b/net/mac80211/ibss.c -@@ -35,6 +35,76 @@ - - #define IEEE80211_IBSS_MAX_STA_ENTRIES 128 - -+static bool ieee80211_can_use_ext_chan(struct ieee80211_sub_if_data *sdata, -+ struct ieee80211_channel *channel, -+ enum nl80211_channel_type channel_type) -+{ -+ /* check if we are legally allowed to use HT extension channel */ -+ if ((channel_type == NL80211_CHAN_HT40PLUS) || -+ (channel_type == NL80211_CHAN_HT40MINUS)) { -+ int sec_freq = channel->center_freq + -+ (channel_type == NL80211_CHAN_HT40PLUS ? 20 : -20); -+ struct ieee80211_channel *sec_chan = -+ ieee80211_get_channel(sdata->wdev.wiphy, sec_freq); -+ if (!sec_chan || sec_chan->flags & (IEEE80211_CHAN_DISABLED | -+ IEEE80211_CHAN_PASSIVE_SCAN | -+ IEEE80211_CHAN_NO_IBSS | -+ IEEE80211_CHAN_RADAR)) { -+ return false; -+ } -+ } -+ return true; -+} -+ -+static void ieee80211_update_ht_elems(struct ieee80211_sub_if_data *sdata, -+ struct ieee80211_mgmt *mgmt, -+ struct ieee80211_ht_info *ht_info) -+{ -+ struct ieee80211_local *local = sdata->local; -+ struct ieee80211_supported_band *sband = -+ local->hw.wiphy->bands[local->oper_channel->band]; -+ enum nl80211_channel_type channel_type = -+ ieee80211_ht_info_to_channel_type(ht_info); -+ -+ if (!ieee80211_can_use_ext_chan(sdata, local->oper_channel, channel_type)) -+ channel_type = NL80211_CHAN_HT20; -+ -+ if (channel_type != local->_oper_channel_type) { -+ struct sk_buff *skb = rcu_dereference_protected( -+ sdata->u.ibss.presp, -+ lockdep_is_held(&ifibss->mtx)); -+ struct sk_buff *nskb; -+ u8 *ht_ie; -+ -+ /* update HT IE. If not yet existing, create one */ -+ nskb = skb_copy(skb, GFP_ATOMIC); -+ ht_ie = (u8 *)cfg80211_find_ie(WLAN_EID_HT_CAPABILITY, -+ (const u8 *)(nskb->data + 24 + -+ sizeof(mgmt->u.beacon)), -+ nskb->len - 24 - -+ sizeof(mgmt->u.beacon)); -+ if (!ht_ie) -+ ht_ie = skb_put(nskb, 4 + -+ sizeof(struct ieee80211_ht_cap) + -+ sizeof(struct ieee80211_ht_info)); -+ -+ ht_ie = ieee80211_ie_build_ht_cap(ht_ie, sband, -+ sband->ht_cap.cap); -+ ht_ie = ieee80211_ie_build_ht_info(ht_ie, &sband->ht_cap, -+ local->oper_channel, channel_type); -+ rcu_assign_pointer(sdata->u.ibss.presp, nskb); -+ kfree_skb(skb); -+ -+ if(!ieee80211_set_channel_type(local, sdata, channel_type)) { -+ channel_type = NL80211_CHAN_HT20; -+ WARN_ON(!ieee80211_set_channel_type(local, sdata, -+ channel_type)); -+ } -+ -+ ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); -+ } -+ -+} - - static void ieee80211_rx_mgmt_auth_ibss(struct ieee80211_sub_if_data *sdata, - struct ieee80211_mgmt *mgmt, -@@ -64,6 +134,7 @@ static void ieee80211_rx_mgmt_auth_ibss( - static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, - const u8 *bssid, const int beacon_int, - struct ieee80211_channel *chan, -+ enum nl80211_channel_type channel_type, - const u32 basic_rates, - const u16 capability, u64 tsf) - { -@@ -104,8 +175,17 @@ static void __ieee80211_sta_join_ibss(st - - sdata->drop_unencrypted = capability & WLAN_CAPABILITY_PRIVACY ? 1 : 0; - -+ /* entering a legacy IBSS. Use given HT configuration. */ -+ if (channel_type == NL80211_CHAN_NO_HT) -+ channel_type = ifibss->channel_type; - local->oper_channel = chan; -- WARN_ON(!ieee80211_set_channel_type(local, sdata, NL80211_CHAN_NO_HT)); -+ -+ /* if phy is on a different extension channel, setting ht40 will fail */ -+ if (!ieee80211_set_channel_type(local, sdata, channel_type)) { -+ channel_type = NL80211_CHAN_HT20; -+ WARN_ON(!ieee80211_set_channel_type(local, sdata, -+ channel_type)); -+ } - ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); - - sband = local->hw.wiphy->bands[chan->band]; -@@ -171,6 +251,18 @@ static void __ieee80211_sta_join_ibss(st - memcpy(skb_put(skb, ifibss->ie_len), - ifibss->ie, ifibss->ie_len); - -+ /* add HT capability and information IEs */ -+ if (channel_type != NL80211_CHAN_NO_HT && sband->ht_cap.ht_supported) { -+ 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_info(pos, -+ &sband->ht_cap, -+ chan, -+ channel_type); -+ } -+ - if (local->hw.queues >= 4) { - pos = skb_put(skb, 9); - *pos++ = WLAN_EID_VENDOR_SPECIFIC; -@@ -219,6 +311,8 @@ static void ieee80211_sta_join_ibss(stru - u32 basic_rates; - int i, j; - u16 beacon_int = cbss->beacon_interval; -+ const u8 *ht_info_ie; -+ enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT; - - lockdep_assert_held(&sdata->u.ibss.mtx); - -@@ -242,9 +336,23 @@ static void ieee80211_sta_join_ibss(stru - } - } - -+ ht_info_ie = ieee80211_bss_get_ie(cbss, WLAN_EID_HT_INFORMATION); -+ if (ht_info_ie) -+ channel_type = ieee80211_ht_info_to_channel_type( -+ (struct ieee80211_ht_info *) (ht_info_ie + 2)); -+ -+ if (!ieee80211_can_use_ext_chan(sdata, cbss->channel, channel_type)) { -+ channel_type = NL80211_CHAN_HT20; -+#ifdef CONFIG_MAC80211_IBSS_DEBUG -+ printk(KERN_DEBUG "%s: IBSS not allowed on secondary channel\n", -+ sdata->name); -+#endif -+ } -+ - __ieee80211_sta_join_ibss(sdata, cbss->bssid, - beacon_int, - cbss->channel, -+ channel_type, - basic_rates, - cbss->capability, - cbss->tsf); -@@ -310,11 +418,24 @@ static void ieee80211_rx_bss_info(struct - } else - sta = ieee80211_ibss_add_sta(sdata, mgmt->bssid, - mgmt->sa, supp_rates, -- GFP_ATOMIC); -+ elems->ht_cap_elem, GFP_ATOMIC); - } - -- if (sta && elems->wmm_info) -- set_sta_flags(sta, WLAN_STA_WME); -+ if (sta) { -+ if (elems->wmm_info) -+ set_sta_flags(sta, WLAN_STA_WME); -+ -+ /* remote station uses ht */ -+ if (elems->ht_info_elem) { -+ ieee80211_update_ht_elems(sdata, mgmt, -+ elems->ht_info_elem); -+ ieee80211_ht_cap_ie_to_sta_ht_cap( -+ local->hw.wiphy->bands[ -+ local->oper_channel->band], -+ elems->ht_cap_elem, -+ &sta->sta.ht_cap); -+ } -+ } - - rcu_read_unlock(); - } -@@ -404,7 +525,7 @@ static void ieee80211_rx_bss_info(struct - ieee80211_sta_join_ibss(sdata, bss); - supp_rates = ieee80211_sta_get_rates(local, elems, band); - ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa, -- supp_rates, GFP_KERNEL); -+ supp_rates, elems->ht_cap_elem, GFP_KERNEL); - } - - put_bss: -@@ -417,7 +538,8 @@ static void ieee80211_rx_bss_info(struct - * must be callable in atomic context. - */ - struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata, -- u8 *bssid,u8 *addr, u32 supp_rates, -+ u8 *bssid, u8 *addr, u32 supp_rates, -+ struct ieee80211_ht_cap *ht_cap, - gfp_t gfp) - { - struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; -@@ -458,6 +580,11 @@ struct sta_info *ieee80211_ibss_add_sta( - sta->sta.supp_rates[band] = supp_rates | - ieee80211_mandatory_rates(local, band); - -+ /* fill in ht rates */ -+ if (ht_cap) -+ ieee80211_ht_cap_ie_to_sta_ht_cap(local->hw.wiphy->bands[band], -+ ht_cap, &sta->sta.ht_cap); -+ - rate_control_rate_init(sta); - - /* If it fails, maybe we raced another insertion? */ -@@ -556,8 +683,8 @@ static void ieee80211_sta_create_ibss(st - sdata->drop_unencrypted = 0; - - __ieee80211_sta_join_ibss(sdata, bssid, sdata->vif.bss_conf.beacon_int, -- ifibss->channel, ifibss->basic_rates, -- capability, 0); -+ ifibss->channel, ifibss->channel_type, -+ ifibss->basic_rates, capability, 0); - } - - /* -@@ -594,10 +721,10 @@ static void ieee80211_sta_find_ibss(stru - chan = ifibss->channel; - if (!is_zero_ether_addr(ifibss->bssid)) - bssid = ifibss->bssid; -- cbss = cfg80211_get_bss(local->hw.wiphy, chan, bssid, -+ cbss = cfg80211_get_bss_ht(local->hw.wiphy, chan, bssid, - ifibss->ssid, ifibss->ssid_len, - WLAN_CAPABILITY_IBSS | WLAN_CAPABILITY_PRIVACY, -- capability); -+ capability, ifibss->channel_type); - - if (cbss) { - struct ieee80211_bss *bss; -@@ -896,10 +1023,15 @@ int ieee80211_ibss_join(struct ieee80211 - struct sk_buff *skb; - - skb = dev_alloc_skb(sdata->local->hw.extra_tx_headroom + -- 36 /* bitrates */ + -- 34 /* SSID */ + -- 3 /* DS params */ + -- 4 /* IBSS params */ + -+ sizeof(struct ieee80211_hdr_3addr) + -+ 12 /* struct ieee80211_mgmt.u.beacon */ + -+ 2 + IEEE80211_MAX_SSID_LEN /* max SSID */ + -+ 2 + 8 /* max Supported Rates */ + -+ 3 /* max DS params */ + -+ 4 /* IBSS params */ + -+ 2 + (IEEE80211_MAX_SUPP_RATES - 8) + -+ 2 + sizeof(struct ieee80211_ht_cap) + -+ 2 + sizeof(struct ieee80211_ht_info) + - params->ie_len); - if (!skb) - return -ENOMEM; -@@ -920,13 +1052,15 @@ int ieee80211_ibss_join(struct ieee80211 - sdata->vif.bss_conf.beacon_int = params->beacon_interval; - - sdata->u.ibss.channel = params->channel; -+ sdata->u.ibss.channel_type = params->channel_type; - sdata->u.ibss.fixed_channel = params->channel_fixed; - - /* fix ourselves to that channel now already */ - if (params->channel_fixed) { - sdata->local->oper_channel = params->channel; -- WARN_ON(!ieee80211_set_channel_type(sdata->local, sdata, -- NL80211_CHAN_NO_HT)); -+ if(!ieee80211_set_channel_type(sdata->local, sdata, -+ params->channel_type)) -+ return -EINVAL; - } - - if (params->ie) { ---- a/net/mac80211/rx.c -+++ b/net/mac80211/rx.c -@@ -2164,7 +2164,8 @@ ieee80211_rx_h_action(struct ieee80211_r - if (sdata->vif.type != NL80211_IFTYPE_STATION && - sdata->vif.type != NL80211_IFTYPE_AP_VLAN && - sdata->vif.type != NL80211_IFTYPE_AP && -- sdata->vif.type != NL80211_IFTYPE_WDS) -+ sdata->vif.type != NL80211_IFTYPE_WDS && -+ sdata->vif.type != NL80211_IFTYPE_ADHOC) - break; - - /* verify action_code is present */ -@@ -2699,7 +2700,8 @@ static int prepare_for_handlers(struct i - else - rate_idx = status->rate_idx; - rx->sta = ieee80211_ibss_add_sta(sdata, bssid, -- hdr->addr2, BIT(rate_idx), GFP_ATOMIC); -+ hdr->addr2, BIT(rate_idx), NULL, -+ GFP_ATOMIC); - } - break; - case NL80211_IFTYPE_MESH_POINT: ---- a/net/mac80211/agg-rx.c -+++ b/net/mac80211/agg-rx.c -@@ -182,6 +182,8 @@ static void ieee80211_send_addba_resp(st - 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); - - mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | - IEEE80211_STYPE_ACTION); diff --git a/package/mac80211/patches/400-ath_move_debug_code.patch b/package/mac80211/patches/400-ath_move_debug_code.patch index f92d38f246..c322dd3e5b 100644 --- a/package/mac80211/patches/400-ath_move_debug_code.patch +++ b/package/mac80211/patches/400-ath_move_debug_code.patch @@ -11,7 +11,7 @@ + debug.o --- a/drivers/net/wireless/ath/ath.h +++ b/drivers/net/wireless/ath/ath.h -@@ -274,13 +274,6 @@ void ath_dbg(struct ath_common *common, +@@ -272,13 +272,6 @@ void ath_dbg(struct ath_common *common, #endif /* CONFIG_ATH_DEBUG */ /** Returns string describing opmode, or NULL if unknown mode. */ diff --git a/package/mac80211/patches/402-ath9k_blink_default.patch b/package/mac80211/patches/402-ath9k_blink_default.patch index 0721227b94..6fa7f734c4 100644 --- a/package/mac80211/patches/402-ath9k_blink_default.patch +++ b/package/mac80211/patches/402-ath9k_blink_default.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c -@@ -35,7 +35,7 @@ int ath9k_modparam_nohwcrypt; +@@ -36,7 +36,7 @@ int ath9k_modparam_nohwcrypt; module_param_named(nohwcrypt, ath9k_modparam_nohwcrypt, int, 0444); MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption"); diff --git a/package/mac80211/patches/403-ath9k-fix-invalid-mac-address-handling.patch b/package/mac80211/patches/403-ath9k-fix-invalid-mac-address-handling.patch index cc59b75fe7..65853b970a 100644 --- a/package/mac80211/patches/403-ath9k-fix-invalid-mac-address-handling.patch +++ b/package/mac80211/patches/403-ath9k-fix-invalid-mac-address-handling.patch @@ -1,14 +1,14 @@ --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c -@@ -16,6 +16,7 @@ - +@@ -17,6 +17,7 @@ #include #include + #include +#include #include #include "hw.h" -@@ -460,8 +461,16 @@ static int ath9k_hw_init_macaddr(struct +@@ -465,8 +466,16 @@ static int ath9k_hw_init_macaddr(struct common->macaddr[2 * i] = eeval >> 8; common->macaddr[2 * i + 1] = eeval & 0xff; } diff --git a/package/mac80211/patches/404-ath_regd_optional.patch b/package/mac80211/patches/404-ath_regd_optional.patch index e3e37e8001..2cae8234e7 100644 --- a/package/mac80211/patches/404-ath_regd_optional.patch +++ b/package/mac80211/patches/404-ath_regd_optional.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/ath/regd.c +++ b/drivers/net/wireless/ath/regd.c -@@ -193,6 +193,10 @@ ath_reg_apply_beaconing_flags(struct wip +@@ -194,6 +194,10 @@ ath_reg_apply_beaconing_flags(struct wip u32 bandwidth = 0; int r; @@ -11,7 +11,7 @@ for (band = 0; band < IEEE80211_NUM_BANDS; band++) { if (!wiphy->bands[band]) -@@ -252,6 +256,10 @@ ath_reg_apply_active_scan_flags(struct w +@@ -253,6 +257,10 @@ ath_reg_apply_active_scan_flags(struct w u32 bandwidth = 0; int r; @@ -20,9 +20,9 @@ +#endif + sband = wiphy->bands[IEEE80211_BAND_2GHZ]; - - /* -@@ -299,6 +307,10 @@ static void ath_reg_apply_radar_flags(st + if (!sband) + return; +@@ -302,6 +310,10 @@ static void ath_reg_apply_radar_flags(st struct ieee80211_channel *ch; unsigned int i; @@ -33,7 +33,7 @@ if (!wiphy->bands[IEEE80211_BAND_5GHZ]) return; -@@ -466,6 +478,10 @@ ath_regd_init_wiphy(struct ath_regulator +@@ -469,6 +481,10 @@ ath_regd_init_wiphy(struct ath_regulator { const struct ieee80211_regdomain *regd; diff --git a/package/mac80211/patches/405-world_regd_fixup.patch b/package/mac80211/patches/405-world_regd_fixup.patch index f08063c8f4..48dc3fd882 100644 --- a/package/mac80211/patches/405-world_regd_fixup.patch +++ b/package/mac80211/patches/405-world_regd_fixup.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/ath/regd.c +++ b/drivers/net/wireless/ath/regd.c -@@ -37,7 +37,8 @@ +@@ -38,7 +38,8 @@ NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_OFDM) /* We allow IBSS on these on a case by case basis by regulatory domain */ @@ -10,7 +10,7 @@ NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS) #define ATH9K_5GHZ_5470_5850 REG_RULE(5470-10, 5850+10, 40, 0, 30,\ NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS) -@@ -55,57 +56,56 @@ +@@ -56,57 +57,56 @@ #define ATH9K_5GHZ_NO_MIDBAND ATH9K_5GHZ_5150_5350, \ ATH9K_5GHZ_5725_5850 diff --git a/package/mac80211/patches/406-regd_no_assoc_hints.patch b/package/mac80211/patches/406-regd_no_assoc_hints.patch index 14ea04b5af..19336830fe 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 -@@ -1653,6 +1653,8 @@ void regulatory_hint_11d(struct wiphy *w +@@ -1656,6 +1656,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)) -@@ -1859,6 +1861,8 @@ static void restore_regulatory_settings( +@@ -1862,6 +1864,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 f9050d56a4..0dbb950319 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 -@@ -1473,15 +1473,6 @@ static int ath9k_add_interface(struct ie +@@ -1448,15 +1448,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); -@@ -1507,15 +1498,6 @@ static int ath9k_change_interface(struct +@@ -1482,15 +1473,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 65491e002b..a964e70e52 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 -@@ -1866,7 +1866,7 @@ ath5k_beacon_send(struct ath5k_hw *ah) +@@ -1860,7 +1860,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); -@@ -1951,7 +1951,7 @@ ath5k_beacon_update_timers(struct ath5k_ +@@ -1945,7 +1945,7 @@ ath5k_beacon_update_timers(struct ath5k_ u64 hw_tsf; intval = ah->bintval & AR5K_BEACON_PERIOD; diff --git a/package/mac80211/patches/500-ath9k_eeprom_debugfs.patch b/package/mac80211/patches/500-ath9k_eeprom_debugfs.patch index 012a6bea1b..91ef8c4018 100644 --- a/package/mac80211/patches/500-ath9k_eeprom_debugfs.patch +++ b/package/mac80211/patches/500-ath9k_eeprom_debugfs.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c -@@ -1585,6 +1585,53 @@ static const struct file_operations fops +@@ -1616,6 +1616,53 @@ static const struct file_operations fops }; @@ -54,7 +54,7 @@ int ath9k_init_debug(struct ath_hw *ah) { struct ath_common *common = ath9k_hw_common(ah); -@@ -1643,6 +1690,9 @@ int ath9k_init_debug(struct ath_hw *ah) +@@ -1674,6 +1721,9 @@ int ath9k_init_debug(struct ath_hw *ah) debugfs_create_u32("gpio_val", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, &sc->sc_ah->gpio_val); diff --git a/package/mac80211/patches/510-ath9k_intr_mitigation_tweak.patch b/package/mac80211/patches/510-ath9k_intr_mitigation_tweak.patch index 6c29e9cbc3..72da8d8315 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 -@@ -1674,8 +1674,8 @@ int ath9k_hw_reset(struct ath_hw *ah, st +@@ -1715,8 +1715,8 @@ int ath9k_hw_reset(struct ath_hw *ah, st REG_WRITE(ah, AR_OBS, 8); if (ah->config.rx_intr_mitigation) { diff --git a/package/mac80211/patches/511-ath9k_increase_bcbuf.patch b/package/mac80211/patches/511-ath9k_increase_bcbuf.patch index 483b382259..b7bc7d2280 100644 --- a/package/mac80211/patches/511-ath9k_increase_bcbuf.patch +++ b/package/mac80211/patches/511-ath9k_increase_bcbuf.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h -@@ -363,7 +363,7 @@ struct ath_vif { +@@ -366,7 +366,7 @@ struct ath_vif { * number of beacon intervals, the game's up. */ #define BSTUCK_THRESH 9 @@ -11,7 +11,7 @@ #define IEEE80211_MS_TO_TU(x) (((x) * 1000) / 1024) --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c -@@ -382,8 +382,8 @@ static void ath9k_hw_init_config(struct +@@ -388,8 +388,8 @@ static void ath9k_hw_init_config(struct { int i; diff --git a/package/mac80211/patches/512-ath9k_reduce_rxbuf.patch b/package/mac80211/patches/512-ath9k_reduce_rxbuf.patch index cf03404e90..79d51e8e50 100644 --- a/package/mac80211/patches/512-ath9k_reduce_rxbuf.patch +++ b/package/mac80211/patches/512-ath9k_reduce_rxbuf.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h -@@ -120,7 +120,7 @@ void ath_descdma_cleanup(struct ath_soft +@@ -121,7 +121,7 @@ void ath_descdma_cleanup(struct ath_soft /* RX / TX */ /***********/ diff --git a/package/mac80211/patches/513-ath9k_channelbw_debugfs.patch b/package/mac80211/patches/513-ath9k_channelbw_debugfs.patch index 4ac3e1c3d3..ded102e144 100644 --- a/package/mac80211/patches/513-ath9k_channelbw_debugfs.patch +++ b/package/mac80211/patches/513-ath9k_channelbw_debugfs.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h -@@ -585,6 +585,7 @@ struct ath_softc { +@@ -591,6 +591,7 @@ struct ath_softc { struct ieee80211_hw *hw; struct device *dev; @@ -8,21 +8,89 @@ int chan_idx; int chan_is_ht; struct survey_info *cur_survey; +@@ -654,6 +655,7 @@ struct ath_softc { + u8 ant_tx, ant_rx; + }; + ++int ath9k_config(struct ieee80211_hw *hw, u32 changed); + void ath9k_tasklet(unsigned long data); + int ath_cabq_update(struct ath_softc *); + --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c -@@ -1693,6 +1693,9 @@ int ath9k_init_debug(struct ath_hw *ah) +@@ -1663,6 +1663,50 @@ static const struct file_operations fops + .owner = THIS_MODULE + }; + ++ ++static ssize_t read_file_chan_bw(struct file *file, char __user *user_buf, ++ size_t count, loff_t *ppos) ++{ ++ struct ath_softc *sc = file->private_data; ++ char buf[32]; ++ unsigned int len; ++ ++ len = sprintf(buf, "0x%08x\n", sc->chan_bw); ++ return simple_read_from_buffer(user_buf, count, ppos, buf, len); ++} ++ ++static ssize_t write_file_chan_bw(struct file *file, const char __user *user_buf, ++ size_t count, loff_t *ppos) ++{ ++ struct ath_softc *sc = file->private_data; ++ unsigned long chan_bw; ++ char buf[32]; ++ ssize_t len; ++ ++ len = min(count, sizeof(buf) - 1); ++ if (copy_from_user(buf, user_buf, len)) ++ return -EFAULT; ++ ++ buf[len] = '\0'; ++ if (strict_strtoul(buf, 0, &chan_bw)) ++ return -EINVAL; ++ ++ sc->chan_bw = chan_bw; ++ if (!sc->ps_idle) ++ ath9k_config(sc->hw, IEEE80211_CONF_CHANGE_CHANNEL); ++ ++ return count; ++} ++ ++static const struct file_operations fops_chanbw = { ++ .read = read_file_chan_bw, ++ .write = write_file_chan_bw, ++ .open = ath9k_debugfs_open, ++ .owner = THIS_MODULE, ++ .llseek = default_llseek, ++}; ++ ++ + int ath9k_init_debug(struct ath_hw *ah) + { + struct ath_common *common = ath9k_hw_common(ah); +@@ -1724,6 +1768,9 @@ int ath9k_init_debug(struct ath_hw *ah) debugfs_create_file("eeprom", S_IRUSR, sc->debug.debugfs_phy, sc, &fops_eeprom); -+ debugfs_create_u32("chanbw", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, -+ &sc->chan_bw); ++ debugfs_create_file("chanbw", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, ++ sc, &fops_chanbw); + sc->debug.regidx = 0; memset(&sc->debug.bb_mac_samp, 0, sizeof(sc->debug.bb_mac_samp)); sc->debug.sampidx = 0; --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c -@@ -1636,9 +1636,10 @@ static int ath9k_config(struct ieee80211 +@@ -1554,7 +1554,7 @@ static void ath9k_disable_ps(struct ath_ + + } + +-static int ath9k_config(struct ieee80211_hw *hw, u32 changed) ++int ath9k_config(struct ieee80211_hw *hw, u32 changed) + { + struct ath_softc *sc = hw->priv; + struct ath_hw *ah = sc->sc_ah; +@@ -1606,9 +1606,10 @@ static int ath9k_config(struct ieee80211 if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { struct ieee80211_channel *curchan = hw->conf.channel; @@ -34,7 +102,7 @@ unsigned long flags; if (ah->curchan) -@@ -1691,7 +1692,23 @@ static int ath9k_config(struct ieee80211 +@@ -1661,7 +1662,23 @@ static int ath9k_config(struct ieee80211 memset(&sc->survey[pos], 0, sizeof(struct survey_info)); } @@ -61,9 +129,9 @@ return -EINVAL; --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c -@@ -1509,6 +1509,10 @@ int ath9k_hw_reset(struct ath_hw *ah, st - (AR_SREV_9300_20_OR_LATER(ah) && IS_CHAN_5GHZ(chan))) - bChannelChange = false; +@@ -1549,6 +1549,10 @@ int ath9k_hw_reset(struct ath_hw *ah, st + caldata->rtt_hist.num_readings) + allow_fbs = true; + if (!ah->curchan || ((ah->curchan->channelFlags ^ chan->channelFlags) & + (CHANNEL_HALF | CHANNEL_QUARTER))) diff --git a/package/mac80211/patches/520-mac80211_minstrel_ht_aggr_delay.patch b/package/mac80211/patches/520-mac80211_minstrel_ht_aggr_delay.patch index 282c63a3f1..8f074f0217 100644 --- a/package/mac80211/patches/520-mac80211_minstrel_ht_aggr_delay.patch +++ b/package/mac80211/patches/520-mac80211_minstrel_ht_aggr_delay.patch @@ -1,6 +1,6 @@ --- a/net/mac80211/rc80211_minstrel_ht.c +++ b/net/mac80211/rc80211_minstrel_ht.c -@@ -355,10 +355,12 @@ minstrel_downgrade_rate(struct minstrel_ +@@ -357,10 +357,12 @@ minstrel_downgrade_rate(struct minstrel_ } static void @@ -14,7 +14,7 @@ u16 tid; if (unlikely(!ieee80211_is_data_qos(hdr->frame_control))) -@@ -374,6 +376,12 @@ minstrel_aggr_check(struct minstrel_priv +@@ -376,6 +378,12 @@ minstrel_aggr_check(struct minstrel_priv if (skb_get_queue_mapping(skb) == IEEE80211_AC_VO) return; @@ -27,7 +27,7 @@ ieee80211_start_tx_ba_session(pubsta, tid, 5000); } -@@ -453,7 +461,7 @@ minstrel_ht_tx_status(void *priv, struct +@@ -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)) diff --git a/package/mac80211/patches/521-mac80211_ht_change_rate_update.patch b/package/mac80211/patches/521-mac80211_ht_change_rate_update.patch index d2f1982339..75087028a2 100644 --- a/package/mac80211/patches/521-mac80211_ht_change_rate_update.patch +++ b/package/mac80211/patches/521-mac80211_ht_change_rate_update.patch @@ -1,6 +1,6 @@ --- a/net/mac80211/main.c +++ b/net/mac80211/main.c -@@ -239,7 +239,9 @@ void ieee80211_bss_info_change_notify(st +@@ -237,7 +237,9 @@ void ieee80211_bss_info_change_notify(st u32 changed) { struct ieee80211_local *local = sdata->local; @@ -10,7 +10,7 @@ if (!changed) return; -@@ -269,6 +271,22 @@ void ieee80211_bss_info_change_notify(st +@@ -267,6 +269,22 @@ void ieee80211_bss_info_change_notify(st switch (sdata->vif.type) { case NL80211_IFTYPE_AP: diff --git a/package/mac80211/patches/522-mac80211_reduce_txqueuelen.patch b/package/mac80211/patches/522-mac80211_reduce_txqueuelen.patch index 948d2043fc..51e649ee81 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 -@@ -685,6 +685,7 @@ static const struct net_device_ops ieee8 +@@ -699,6 +699,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/560-minstrel_ht_optimize.patch b/package/mac80211/patches/523-minstrel_ht_optimize.patch similarity index 89% rename from package/mac80211/patches/560-minstrel_ht_optimize.patch rename to package/mac80211/patches/523-minstrel_ht_optimize.patch index d27ca5947f..8e804cae8b 100644 --- a/package/mac80211/patches/560-minstrel_ht_optimize.patch +++ b/package/mac80211/patches/523-minstrel_ht_optimize.patch @@ -40,7 +40,7 @@ /* * Update rate statistics and select new primary rates * -@@ -292,6 +307,7 @@ minstrel_ht_update_stats(struct minstrel +@@ -294,6 +309,7 @@ minstrel_ht_update_stats(struct minstrel } } @@ -48,7 +48,7 @@ mi->stats_update = jiffies; } -@@ -330,8 +346,8 @@ minstrel_next_sample_idx(struct minstrel +@@ -332,8 +348,8 @@ minstrel_next_sample_idx(struct minstrel } static void @@ -59,7 +59,7 @@ { int group, orig_group; -@@ -350,6 +366,7 @@ minstrel_downgrade_rate(struct minstrel_ +@@ -352,6 +368,7 @@ minstrel_downgrade_rate(struct minstrel_ *idx = mi->groups[group].max_tp_rate; else *idx = mi->groups[group].max_tp_rate2; @@ -67,7 +67,7 @@ break; } } -@@ -450,13 +467,13 @@ minstrel_ht_tx_status(void *priv, struct +@@ -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)) @@ -83,7 +83,7 @@ if (time_after(jiffies, mi->stats_update + (mp->update_interval / 2 * HZ) / 1000)) { minstrel_ht_update_stats(mp, mi); -@@ -521,7 +538,6 @@ minstrel_calc_retransmit(struct minstrel +@@ -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, @@ -91,7 +91,7 @@ bool sample, bool rtscts) { const struct mcs_group *group = &minstrel_mcs_groups[index / MCS_GROUP_RATES]; -@@ -609,6 +625,7 @@ minstrel_ht_get_rate(void *priv, struct +@@ -611,6 +627,7 @@ minstrel_ht_get_rate(void *priv, struct struct minstrel_priv *mp = priv; int sample_idx; bool sample = false; @@ -99,7 +99,7 @@ if (rate_control_send_low(sta, priv_sta, txrc)) return; -@@ -634,11 +651,10 @@ minstrel_ht_get_rate(void *priv, struct +@@ -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, @@ -113,7 +113,7 @@ } if (mp->hw->max_rates >= 3) { -@@ -648,33 +664,27 @@ minstrel_ht_get_rate(void *priv, struct +@@ -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) @@ -157,7 +157,7 @@ mi->total_packets++; -@@ -766,6 +776,7 @@ minstrel_ht_update_caps(void *priv, stru +@@ -768,6 +778,7 @@ minstrel_ht_update_caps(void *priv, stru if (!n_supported) goto use_legacy; diff --git a/package/mac80211/patches/530-mac80211_cur_txpower.patch b/package/mac80211/patches/530-mac80211_cur_txpower.patch index 4ca84a637e..0fa6a229fd 100644 --- a/package/mac80211/patches/530-mac80211_cur_txpower.patch +++ b/package/mac80211/patches/530-mac80211_cur_txpower.patch @@ -1,6 +1,6 @@ --- a/include/net/mac80211.h +++ b/include/net/mac80211.h -@@ -798,7 +798,7 @@ enum ieee80211_smps_mode { +@@ -816,7 +816,7 @@ enum ieee80211_smps_mode { */ struct ieee80211_conf { u32 flags; @@ -11,7 +11,7 @@ u16 listen_interval; --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c -@@ -1568,7 +1568,7 @@ static int ieee80211_get_tx_power(struct +@@ -1677,7 +1677,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 -@@ -210,6 +210,7 @@ int ieee80211_hw_config(struct ieee80211 +@@ -208,6 +208,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 894d780420..760f4d754e 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 -@@ -1714,6 +1714,8 @@ static int ath9k_config(struct ieee80211 +@@ -1684,6 +1684,8 @@ int ath9k_config(struct ieee80211_hw *hw return -EINVAL; } @@ -9,11 +9,11 @@ /* * The most recent snapshot of channel->noisefloor for the old * channel is only available after the hardware reset. Copy it to -@@ -1731,6 +1733,7 @@ static int ath9k_config(struct ieee80211 +@@ -1699,6 +1701,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); - ath9k_ps_restore(sc); + conf->cur_power_level = sc->curtxpow / 2; } - if (disable_radio) { + mutex_unlock(&sc->mutex); diff --git a/package/mac80211/patches/540-ath9k_limit_qlen.patch b/package/mac80211/patches/540-ath9k_limit_qlen.patch index e4d56485b4..237966eb03 100644 --- a/package/mac80211/patches/540-ath9k_limit_qlen.patch +++ b/package/mac80211/patches/540-ath9k_limit_qlen.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h -@@ -237,6 +237,7 @@ struct ath_atx_tid { +@@ -238,6 +238,7 @@ struct ath_atx_tid { struct ath_node *an; struct ath_atx_ac *ac; unsigned long tx_buf[BITS_TO_LONGS(ATH_TID_MAX_BUFS)]; @@ -8,7 +8,7 @@ u16 seq_start; u16 seq_next; u16 baw_size; -@@ -282,6 +283,9 @@ struct ath_tx_control { +@@ -284,6 +285,9 @@ struct ath_tx_control { * (axq_qnum). */ struct ath_tx { @@ -20,7 +20,7 @@ spinlock_t txbuflock; --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c -@@ -1654,6 +1654,10 @@ int ath9k_init_debug(struct ath_hw *ah) +@@ -1729,6 +1729,10 @@ int ath9k_init_debug(struct ath_hw *ah) sc, &fops_wiphy); debugfs_create_file("xmit", S_IRUSR, sc->debug.debugfs_phy, sc, &fops_xmit); @@ -33,7 +33,7 @@ debugfs_create_file("misc", S_IRUSR, sc->debug.debugfs_phy, sc, --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c -@@ -350,6 +350,14 @@ static void ath_tx_count_frames(struct a +@@ -355,6 +355,14 @@ static void ath_tx_count_frames(struct a } } @@ -48,7 +48,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, struct ath_buf *bf, struct list_head *bf_q, -@@ -438,6 +446,8 @@ static void ath_tx_complete_aggr(struct +@@ -443,6 +451,8 @@ static void ath_tx_complete_aggr(struct __skb_queue_head_init(&bf_pending); ath_tx_count_frames(sc, bf, ts, txok, &nframes, &nbad); @@ -57,7 +57,7 @@ while (bf) { u16 seqno = bf->bf_state.seqno; -@@ -816,6 +826,7 @@ static enum ATH_AGGR_STATUS ath_tx_form_ +@@ -823,6 +833,7 @@ static enum ATH_AGGR_STATUS ath_tx_form_ ath_tx_addto_baw(sc, tid, seqno); bf->bf_state.ndelim = ndelim; @@ -65,7 +65,7 @@ __skb_unlink(skb, &tid->buf_q); list_add_tail(&bf->list, bf_q); if (bf_prev) -@@ -1693,6 +1704,8 @@ static void ath_tx_send_ampdu(struct ath +@@ -1682,6 +1693,8 @@ static void ath_tx_send_ampdu(struct ath /* Add sub-frame to BAW */ ath_tx_addto_baw(sc, tid, bf->bf_state.seqno); @@ -74,7 +74,7 @@ /* Queue to h/w without aggregation */ TX_STAT_INC(txctl->txq->axq_qnum, a_queued_hw); bf->bf_lastbf = bf; -@@ -1821,23 +1834,13 @@ error: +@@ -1810,23 +1823,13 @@ error: /* FIXME: tx power */ static void ath_tx_start_dma(struct ath_softc *sc, struct sk_buff *skb, @@ -100,7 +100,7 @@ if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && tid) { /* -@@ -1872,6 +1875,7 @@ int ath_tx_start(struct ieee80211_hw *hw +@@ -1861,6 +1864,7 @@ int ath_tx_start(struct ieee80211_hw *hw struct ieee80211_vif *vif = info->control.vif; struct ath_softc *sc = hw->priv; struct ath_txq *txq = txctl->txq; @@ -108,7 +108,7 @@ int padpos, padsize; int frmlen = skb->len + FCS_LEN; int q; -@@ -1916,6 +1920,24 @@ int ath_tx_start(struct ieee80211_hw *hw +@@ -1903,6 +1907,24 @@ int ath_tx_start(struct ieee80211_hw *hw setup_frame_info(hw, skb, frmlen); @@ -133,7 +133,7 @@ /* * At this point, the vif, hw_key and sta pointers in the tx control * info are no longer valid (overwritten by the ath_frame_info data. -@@ -1930,7 +1952,7 @@ int ath_tx_start(struct ieee80211_hw *hw +@@ -1917,7 +1939,7 @@ int ath_tx_start(struct ieee80211_hw *hw } spin_unlock_bh(&txq->axq_lock); diff --git a/package/mac80211/patches/541-ath9k_sw_retry_reduce.patch b/package/mac80211/patches/541-ath9k_sw_retry_reduce.patch index 1685aabfaa..d83b663fbc 100644 --- a/package/mac80211/patches/541-ath9k_sw_retry_reduce.patch +++ b/package/mac80211/patches/541-ath9k_sw_retry_reduce.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c -@@ -259,14 +259,17 @@ static void ath_tid_drain(struct ath_sof +@@ -264,14 +264,17 @@ static void ath_tid_drain(struct ath_sof } static void ath_tx_set_retry(struct ath_softc *sc, struct ath_txq *txq, @@ -20,15 +20,15 @@ return; hdr = (struct ieee80211_hdr *)skb->data; -@@ -382,6 +385,7 @@ static void ath_tx_complete_aggr(struct +@@ -387,6 +390,7 @@ static void ath_tx_complete_aggr(struct int nframes; u8 tidno; - bool clear_filter; + bool flush = !!(ts->ts_status & ATH9K_TX_FLUSH); + int i, retries; skb = bf->bf_mpdu; hdr = (struct ieee80211_hdr *)skb->data; -@@ -390,6 +394,10 @@ static void ath_tx_complete_aggr(struct +@@ -395,6 +399,10 @@ static void ath_tx_complete_aggr(struct memcpy(rates, tx_info->control.rates, sizeof(rates)); @@ -39,19 +39,19 @@ rcu_read_lock(); sta = ieee80211_find_sta_by_ifaddr(hw, hdr->addr1, hdr->addr2); -@@ -475,7 +483,8 @@ static void ath_tx_complete_aggr(struct +@@ -481,7 +489,8 @@ static void ath_tx_complete_aggr(struct + txpending = 1; } else if (fi->retries < ATH_MAX_SW_RETRIES) { - if (!(ts->ts_status & ATH9K_TXERR_FILT) || - !an->sleeping) + if (txok || !an->sleeping) - ath_tx_set_retry(sc, txq, bf->bf_mpdu); + ath_tx_set_retry(sc, txq, bf->bf_mpdu, + retries); - clear_filter = true; txpending = 1; + } else { --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h -@@ -540,7 +540,7 @@ struct ath_ant_comb { +@@ -546,7 +546,7 @@ struct ath_ant_comb { #define DEFAULT_CACHELINE 32 #define ATH_REGCLASSIDS_MAX 10 #define ATH_CABQ_READY_TIME 80 /* % of beacon interval */ diff --git a/package/mac80211/patches/550-ath9k_ar9280_cold_reset.patch b/package/mac80211/patches/542-ath9k_ar9280_cold_reset.patch similarity index 91% rename from package/mac80211/patches/550-ath9k_ar9280_cold_reset.patch rename to package/mac80211/patches/542-ath9k_ar9280_cold_reset.patch index bbc462077c..fe7afdedc5 100644 --- a/package/mac80211/patches/550-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 -@@ -1371,10 +1371,16 @@ static bool ath9k_hw_set_reset_reg(struc +@@ -1382,10 +1382,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/550-ath9k_debug_remove_packet_rssi.patch b/package/mac80211/patches/550-ath9k_debug_remove_packet_rssi.patch new file mode 100644 index 0000000000..4bd3d552f9 --- /dev/null +++ b/package/mac80211/patches/550-ath9k_debug_remove_packet_rssi.patch @@ -0,0 +1,70 @@ +--- a/drivers/net/wireless/ath/ath9k/debug.c ++++ b/drivers/net/wireless/ath/ath9k/debug.c +@@ -969,34 +969,6 @@ static ssize_t read_file_recv(struct fil + "%18s : %10u\n", "DECRYPT BUSY ERR", + sc->debug.stats.rxstats.decrypt_busy_err); + +- len += snprintf(buf + len, size - len, +- "%18s : %10d\n", "RSSI-CTL0", +- sc->debug.stats.rxstats.rs_rssi_ctl0); +- +- len += snprintf(buf + len, size - len, +- "%18s : %10d\n", "RSSI-CTL1", +- sc->debug.stats.rxstats.rs_rssi_ctl1); +- +- len += snprintf(buf + len, size - len, +- "%18s : %10d\n", "RSSI-CTL2", +- sc->debug.stats.rxstats.rs_rssi_ctl2); +- +- len += snprintf(buf + len, size - len, +- "%18s : %10d\n", "RSSI-EXT0", +- sc->debug.stats.rxstats.rs_rssi_ext0); +- +- len += snprintf(buf + len, size - len, +- "%18s : %10d\n", "RSSI-EXT1", +- sc->debug.stats.rxstats.rs_rssi_ext1); +- +- len += snprintf(buf + len, size - len, +- "%18s : %10d\n", "RSSI-EXT2", +- sc->debug.stats.rxstats.rs_rssi_ext2); +- +- len += snprintf(buf + len, size - len, +- "%18s : %10d\n", "Rx Antenna", +- sc->debug.stats.rxstats.rs_antenna); +- + PHY_ERR("UNDERRUN", ATH9K_PHYERR_UNDERRUN); + PHY_ERR("TIMING", ATH9K_PHYERR_TIMING); + PHY_ERR("PARITY", ATH9K_PHYERR_PARITY); +@@ -1073,16 +1045,6 @@ void ath_debug_stat_rx(struct ath_softc + RX_PHY_ERR_INC(phyerr); + } + +- sc->debug.stats.rxstats.rs_rssi_ctl0 = rs->rs_rssi_ctl0; +- sc->debug.stats.rxstats.rs_rssi_ctl1 = rs->rs_rssi_ctl1; +- sc->debug.stats.rxstats.rs_rssi_ctl2 = rs->rs_rssi_ctl2; +- +- sc->debug.stats.rxstats.rs_rssi_ext0 = rs->rs_rssi_ext0; +- sc->debug.stats.rxstats.rs_rssi_ext1 = rs->rs_rssi_ext1; +- sc->debug.stats.rxstats.rs_rssi_ext2 = rs->rs_rssi_ext2; +- +- sc->debug.stats.rxstats.rs_antenna = rs->rs_antenna; +- + spin_lock(&sc->debug.samp_lock); + RX_SAMP_DBG(jiffies) = jiffies; + RX_SAMP_DBG(rssi_ctl0) = rs->rs_rssi_ctl0; +--- a/drivers/net/wireless/ath/ath9k/debug.h ++++ b/drivers/net/wireless/ath/ath9k/debug.h +@@ -164,13 +164,6 @@ struct ath_rx_stats { + u32 post_delim_crc_err; + u32 decrypt_busy_err; + u32 phy_err_stats[ATH9K_PHYERR_MAX]; +- int8_t rs_rssi_ctl0; +- int8_t rs_rssi_ctl1; +- int8_t rs_rssi_ctl2; +- int8_t rs_rssi_ext0; +- int8_t rs_rssi_ext1; +- int8_t rs_rssi_ext2; +- u8 rs_antenna; + }; + + enum ath_reset_type { diff --git a/package/mac80211/patches/551-ath9k_fix_keymiss_handling.patch b/package/mac80211/patches/551-ath9k_fix_keymiss_handling.patch deleted file mode 100644 index 931c50e0ce..0000000000 --- a/package/mac80211/patches/551-ath9k_fix_keymiss_handling.patch +++ /dev/null @@ -1,93 +0,0 @@ ---- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c -+++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c -@@ -525,8 +525,8 @@ int ath9k_hw_process_rxdesc_edma(struct - rxs->rs_status |= ATH9K_RXERR_DECRYPT; - else if (rxsp->status11 & AR_MichaelErr) - rxs->rs_status |= ATH9K_RXERR_MIC; -- else if (rxsp->status11 & AR_KeyMiss) -- rxs->rs_status |= ATH9K_RXERR_DECRYPT; -+ if (rxsp->status11 & AR_KeyMiss) -+ rxs->rs_status |= ATH9K_RXERR_KEYMISS; - } - - return 0; ---- a/drivers/net/wireless/ath/ath9k/mac.c -+++ b/drivers/net/wireless/ath/ath9k/mac.c -@@ -620,8 +620,8 @@ int ath9k_hw_rxprocdesc(struct ath_hw *a - rs->rs_status |= ATH9K_RXERR_DECRYPT; - else if (ads.ds_rxstatus8 & AR_MichaelErr) - rs->rs_status |= ATH9K_RXERR_MIC; -- else if (ads.ds_rxstatus8 & AR_KeyMiss) -- rs->rs_status |= ATH9K_RXERR_DECRYPT; -+ if (ads.ds_rxstatus8 & AR_KeyMiss) -+ rs->rs_status |= ATH9K_RXERR_KEYMISS; - } - - return 0; ---- a/drivers/net/wireless/ath/ath9k/mac.h -+++ b/drivers/net/wireless/ath/ath9k/mac.h -@@ -181,6 +181,7 @@ struct ath_htc_rx_status { - #define ATH9K_RXERR_FIFO 0x04 - #define ATH9K_RXERR_DECRYPT 0x08 - #define ATH9K_RXERR_MIC 0x10 -+#define ATH9K_RXERR_KEYMISS 0x20 - - #define ATH9K_RX_MORE 0x01 - #define ATH9K_RX_MORE_AGGR 0x02 ---- a/drivers/net/wireless/ath/ath9k/recv.c -+++ b/drivers/net/wireless/ath/ath9k/recv.c -@@ -826,7 +826,8 @@ static bool ath9k_rx_accept(struct ath_c - test_bit(rx_stats->rs_keyix, common->tkip_keymap); - strip_mic = is_valid_tkip && ieee80211_is_data(fc) && - !(rx_stats->rs_status & -- (ATH9K_RXERR_DECRYPT | ATH9K_RXERR_CRC | ATH9K_RXERR_MIC)); -+ (ATH9K_RXERR_DECRYPT | ATH9K_RXERR_CRC | ATH9K_RXERR_MIC | -+ ATH9K_RXERR_KEYMISS)); - - if (!rx_stats->rs_datalen) - return false; -@@ -854,6 +855,8 @@ static bool ath9k_rx_accept(struct ath_c - * descriptors. - */ - if (rx_stats->rs_status != 0) { -+ u8 status_mask; -+ - if (rx_stats->rs_status & ATH9K_RXERR_CRC) { - rxs->flag |= RX_FLAG_FAILED_FCS_CRC; - mic_error = false; -@@ -861,7 +864,8 @@ static bool ath9k_rx_accept(struct ath_c - if (rx_stats->rs_status & ATH9K_RXERR_PHY) - return false; - -- if (rx_stats->rs_status & ATH9K_RXERR_DECRYPT) { -+ if ((rx_stats->rs_status & ATH9K_RXERR_DECRYPT) || -+ (!is_mc && (rx_stats->rs_status & ATH9K_RXERR_KEYMISS))) { - *decrypt_error = true; - mic_error = false; - } -@@ -871,17 +875,14 @@ static bool ath9k_rx_accept(struct ath_c - * decryption and MIC failures. For monitor mode, - * we also ignore the CRC error. - */ -- if (ah->is_monitoring) { -- if (rx_stats->rs_status & -- ~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC | -- ATH9K_RXERR_CRC)) -- return false; -- } else { -- if (rx_stats->rs_status & -- ~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC)) { -- return false; -- } -- } -+ status_mask = ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC | -+ ATH9K_RXERR_KEYMISS; -+ -+ if (ah->is_monitoring) -+ status_mask |= ATH9K_RXERR_CRC; -+ -+ if (rx_stats->rs_status & ~status_mask) -+ return false; - } - - /* diff --git a/package/mac80211/patches/551-ath9k_per_chain_signal_strength.patch b/package/mac80211/patches/551-ath9k_per_chain_signal_strength.patch new file mode 100644 index 0000000000..378fb090b0 --- /dev/null +++ b/package/mac80211/patches/551-ath9k_per_chain_signal_strength.patch @@ -0,0 +1,374 @@ +--- a/include/net/mac80211.h ++++ b/include/net/mac80211.h +@@ -684,6 +684,9 @@ enum mac80211_rx_flags { + * @mactime: value in microseconds of the 64-bit Time Synchronization Function + * (TSF) timer when the first data symbol (MPDU) arrived at the hardware. + * @band: the active band when this frame was received ++ * @chains: bitmask of receive chains for which separate signal strength ++ * values were filled. ++ * @chain_signal: per-chain signal strength, same format as @signal + * @freq: frequency the radio was tuned to when receiving this frame, in MHz + * @signal: signal strength when receiving this frame, either in dBm, in dB or + * unspecified depending on the hardware capabilities flags +@@ -697,6 +700,10 @@ enum mac80211_rx_flags { + struct ieee80211_rx_status { + u64 mactime; + enum ieee80211_band band; ++ ++ u8 chains; ++ s8 chain_signal[4]; ++ + int freq; + int signal; + int antenna; +--- a/net/mac80211/sta_info.h ++++ b/net/mac80211/sta_info.h +@@ -302,6 +302,11 @@ struct sta_info { + unsigned long rx_dropped; + int last_signal; + struct ewma avg_signal; ++ ++ u8 chains; ++ s8 chain_signal_last[4]; ++ struct ewma chain_signal_avg[4]; ++ + /* Plus 1 for non-QoS frames */ + __le16 last_seq_ctrl[NUM_RX_DATA_QUEUES + 1]; + +--- a/net/mac80211/rx.c ++++ b/net/mac80211/rx.c +@@ -1267,6 +1267,7 @@ ieee80211_rx_h_sta_process(struct ieee80 + struct sk_buff *skb = rx->skb; + struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; ++ int i; + + if (!sta) + return RX_CONTINUE; +@@ -1309,6 +1310,19 @@ ieee80211_rx_h_sta_process(struct ieee80 + sta->last_signal = status->signal; + ewma_add(&sta->avg_signal, -status->signal); + ++ if (status->chains) { ++ sta->chains = status->chains; ++ for (i = 0; i < 4; i++) { ++ int signal = status->chain_signal[i]; ++ ++ if (!(status->chains & BIT(i))) ++ continue; ++ ++ sta->chain_signal_last[i] = signal; ++ ewma_add(&sta->chain_signal_avg[i], -signal); ++ } ++ } ++ + /* + * Change STA power saving mode only at the end of a frame + * exchange sequence. +--- a/net/mac80211/sta_info.c ++++ b/net/mac80211/sta_info.c +@@ -304,6 +304,8 @@ struct sta_info *sta_info_alloc(struct i + do_posix_clock_monotonic_gettime(&uptime); + sta->last_connected = uptime.tv_sec; + ewma_init(&sta->avg_signal, 1024, 8); ++ for (i = 0; i < ARRAY_SIZE(sta->chain_signal_avg); i++) ++ ewma_init(&sta->chain_signal_avg[i], 1024, 8); + + if (sta_prepare_rate_control(local, sta, gfp)) { + kfree(sta); +--- a/include/net/cfg80211.h ++++ b/include/net/cfg80211.h +@@ -505,6 +505,8 @@ struct station_parameters { + * @STATION_INFO_CONNECTED_TIME: @connected_time filled + * @STATION_INFO_ASSOC_REQ_IES: @assoc_req_ies filled + * @STATION_INFO_STA_FLAGS: @sta_flags filled ++ * @STATION_INFO_CHAIN_SIGNAL: @chain_signal filled ++ * @STATION_INFO_CHAIN_SIGNAL_AVG: @chain_signal_avg filled + */ + enum station_info_flags { + STATION_INFO_INACTIVE_TIME = 1<<0, +@@ -525,7 +527,9 @@ enum station_info_flags { + STATION_INFO_BSS_PARAM = 1<<15, + STATION_INFO_CONNECTED_TIME = 1<<16, + STATION_INFO_ASSOC_REQ_IES = 1<<17, +- STATION_INFO_STA_FLAGS = 1<<18 ++ STATION_INFO_STA_FLAGS = 1<<18, ++ STATION_INFO_CHAIN_SIGNAL = 1<<19, ++ STATION_INFO_CHAIN_SIGNAL_AVG = 1<<20, + }; + + /** +@@ -605,6 +609,9 @@ struct sta_bss_parameters { + * @plink_state: mesh peer link state + * @signal: signal strength of last received packet in dBm + * @signal_avg: signal strength average in dBm ++ * @chains: bitmask for filled values in @chain_signal, @chain_signal_avg ++ * @chain_signal: per-chain signal strength of last received packet in dBm ++ * @chain_signal_avg: per-chain signal strength average in dBm + * @txrate: current unicast bitrate from this station + * @rxrate: current unicast bitrate to this station + * @rx_packets: packets received from this station +@@ -635,6 +642,11 @@ struct station_info { + u8 plink_state; + s8 signal; + s8 signal_avg; ++ ++ u8 chains; ++ s8 chain_signal[4]; ++ s8 chain_signal_avg[4]; ++ + struct rate_info txrate; + struct rate_info rxrate; + u32 rx_packets; +--- a/drivers/net/wireless/ath/ath9k/mac.h ++++ b/drivers/net/wireless/ath/ath9k/mac.h +@@ -133,12 +133,8 @@ struct ath_rx_status { + u8 rs_rate; + u8 rs_antenna; + u8 rs_more; +- int8_t rs_rssi_ctl0; +- int8_t rs_rssi_ctl1; +- int8_t rs_rssi_ctl2; +- int8_t rs_rssi_ext0; +- int8_t rs_rssi_ext1; +- int8_t rs_rssi_ext2; ++ int8_t rs_rssi_ctl[3]; ++ int8_t rs_rssi_ext[3]; + u8 rs_isaggr; + u8 rs_moreaggr; + 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 + bool *decrypt_error) + { + struct ath_hw *ah = common->ah; ++ int i, j; + + memset(rx_status, 0, sizeof(struct ieee80211_rx_status)); + +@@ -1006,6 +1007,20 @@ static int ath9k_rx_skb_preprocess(struc + rx_status->antenna = rx_stats->rs_antenna; + rx_status->flag |= RX_FLAG_MACTIME_MPDU; + ++ for (i = 0, j = 0; i < ARRAY_SIZE(rx_stats->rs_rssi_ctl); i++) { ++ s8 rssi; ++ ++ if (!(ah->rxchainmask & BIT(i))) ++ continue; ++ ++ rssi = rx_stats->rs_rssi_ctl[i]; ++ if (rssi != ATH9K_RSSI_BAD) { ++ rx_status->chains |= BIT(j); ++ rx_status->chain_signal[j] = ah->noise + rssi; ++ } ++ j++; ++ } ++ + return 0; + } + +@@ -1536,14 +1551,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; +- int main_rssi = rs->rs_rssi_ctl0; +- int alt_rssi = rs->rs_rssi_ctl1; ++ int main_rssi = rs->rs_rssi_ctl[0]; ++ int alt_rssi = rs->rs_rssi_ctl[1]; + int rx_ant_conf, main_ant_conf; + bool short_scan = false; + +- rx_ant_conf = (rs->rs_rssi_ctl2 >> ATH_ANT_RX_CURRENT_SHIFT) & ++ rx_ant_conf = (rs->rs_rssi_ctl[2] >> ATH_ANT_RX_CURRENT_SHIFT) & + ATH_ANT_RX_MASK; +- main_ant_conf = (rs->rs_rssi_ctl2 >> ATH_ANT_RX_MAIN_SHIFT) & ++ main_ant_conf = (rs->rs_rssi_ctl[2] >> ATH_ANT_RX_MAIN_SHIFT) & + ATH_ANT_RX_MASK; + + /* 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 + + /* XXX: Keycache */ + rxs->rs_rssi = MS(rxsp->status5, AR_RxRSSICombined); +- rxs->rs_rssi_ctl0 = MS(rxsp->status1, AR_RxRSSIAnt00); +- rxs->rs_rssi_ctl1 = MS(rxsp->status1, AR_RxRSSIAnt01); +- rxs->rs_rssi_ctl2 = MS(rxsp->status1, AR_RxRSSIAnt02); +- rxs->rs_rssi_ext0 = MS(rxsp->status5, AR_RxRSSIAnt10); +- rxs->rs_rssi_ext1 = MS(rxsp->status5, AR_RxRSSIAnt11); +- rxs->rs_rssi_ext2 = MS(rxsp->status5, AR_RxRSSIAnt12); ++ rxs->rs_rssi_ctl[0] = MS(rxsp->status1, AR_RxRSSIAnt00); ++ rxs->rs_rssi_ctl[1] = MS(rxsp->status1, AR_RxRSSIAnt01); ++ rxs->rs_rssi_ctl[2] = MS(rxsp->status1, AR_RxRSSIAnt02); ++ rxs->rs_rssi_ext[0] = MS(rxsp->status5, AR_RxRSSIAnt10); ++ rxs->rs_rssi_ext[1] = MS(rxsp->status5, AR_RxRSSIAnt11); ++ rxs->rs_rssi_ext[2] = MS(rxsp->status5, AR_RxRSSIAnt12); + + if (rxsp->status11 & AR_RxKeyIdxValid) + rxs->rs_keyix = MS(rxsp->status11, AR_KeyIdx); +--- a/drivers/net/wireless/ath/ath9k/mac.c ++++ b/drivers/net/wireless/ath/ath9k/mac.c +@@ -559,25 +559,25 @@ int ath9k_hw_rxprocdesc(struct ath_hw *a + + if (ads.ds_rxstatus8 & AR_PostDelimCRCErr) { + rs->rs_rssi = ATH9K_RSSI_BAD; +- rs->rs_rssi_ctl0 = ATH9K_RSSI_BAD; +- rs->rs_rssi_ctl1 = ATH9K_RSSI_BAD; +- rs->rs_rssi_ctl2 = ATH9K_RSSI_BAD; +- rs->rs_rssi_ext0 = ATH9K_RSSI_BAD; +- rs->rs_rssi_ext1 = ATH9K_RSSI_BAD; +- rs->rs_rssi_ext2 = ATH9K_RSSI_BAD; ++ rs->rs_rssi_ctl[0] = ATH9K_RSSI_BAD; ++ rs->rs_rssi_ctl[1] = ATH9K_RSSI_BAD; ++ rs->rs_rssi_ctl[2] = ATH9K_RSSI_BAD; ++ rs->rs_rssi_ext[0] = ATH9K_RSSI_BAD; ++ rs->rs_rssi_ext[1] = ATH9K_RSSI_BAD; ++ rs->rs_rssi_ext[2] = ATH9K_RSSI_BAD; + } else { + rs->rs_rssi = MS(ads.ds_rxstatus4, AR_RxRSSICombined); +- rs->rs_rssi_ctl0 = MS(ads.ds_rxstatus0, ++ rs->rs_rssi_ctl[0] = MS(ads.ds_rxstatus0, + AR_RxRSSIAnt00); +- rs->rs_rssi_ctl1 = MS(ads.ds_rxstatus0, ++ rs->rs_rssi_ctl[1] = MS(ads.ds_rxstatus0, + AR_RxRSSIAnt01); +- rs->rs_rssi_ctl2 = MS(ads.ds_rxstatus0, ++ rs->rs_rssi_ctl[2] = MS(ads.ds_rxstatus0, + AR_RxRSSIAnt02); +- rs->rs_rssi_ext0 = MS(ads.ds_rxstatus4, ++ rs->rs_rssi_ext[0] = MS(ads.ds_rxstatus4, + AR_RxRSSIAnt10); +- rs->rs_rssi_ext1 = MS(ads.ds_rxstatus4, ++ rs->rs_rssi_ext[1] = MS(ads.ds_rxstatus4, + AR_RxRSSIAnt11); +- rs->rs_rssi_ext2 = MS(ads.ds_rxstatus4, ++ rs->rs_rssi_ext[2] = MS(ads.ds_rxstatus4, + AR_RxRSSIAnt12); + } + if (ads.ds_rxstatus8 & AR_RxKeyIdxValid) +--- a/drivers/net/wireless/ath/ath9k/debug.c ++++ b/drivers/net/wireless/ath/ath9k/debug.c +@@ -1047,12 +1047,12 @@ void ath_debug_stat_rx(struct ath_softc + + spin_lock(&sc->debug.samp_lock); + RX_SAMP_DBG(jiffies) = jiffies; +- RX_SAMP_DBG(rssi_ctl0) = rs->rs_rssi_ctl0; +- RX_SAMP_DBG(rssi_ctl1) = rs->rs_rssi_ctl1; +- RX_SAMP_DBG(rssi_ctl2) = rs->rs_rssi_ctl2; +- RX_SAMP_DBG(rssi_ext0) = rs->rs_rssi_ext0; +- RX_SAMP_DBG(rssi_ext1) = rs->rs_rssi_ext1; +- RX_SAMP_DBG(rssi_ext2) = rs->rs_rssi_ext2; ++ RX_SAMP_DBG(rssi_ctl0) = rs->rs_rssi_ctl[0]; ++ RX_SAMP_DBG(rssi_ctl1) = rs->rs_rssi_ctl[1]; ++ RX_SAMP_DBG(rssi_ctl2) = rs->rs_rssi_ctl[2]; ++ RX_SAMP_DBG(rssi_ext0) = rs->rs_rssi_ext[0]; ++ RX_SAMP_DBG(rssi_ext1) = rs->rs_rssi_ext[1]; ++ RX_SAMP_DBG(rssi_ext2) = rs->rs_rssi_ext[2]; + RX_SAMP_DBG(antenna) = rs->rs_antenna; + RX_SAMP_DBG(rssi) = rs->rs_rssi; + RX_SAMP_DBG(rate) = rs->rs_rate; +--- a/include/linux/nl80211.h ++++ b/include/linux/nl80211.h +@@ -1621,6 +1621,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. ++ * @NL80211_STA_INFO_CHAIN_SIGNAL: per-chain signal strength of last PPDU ++ * @NL80211_STA_INFO_CHAIN_SIGNAL_AVG: per-chain signal strength average + * @__NL80211_STA_INFO_AFTER_LAST: internal + * @NL80211_STA_INFO_MAX: highest possible station info attribute + */ +@@ -1643,6 +1645,8 @@ enum nl80211_sta_info { + NL80211_STA_INFO_BSS_PARAM, + NL80211_STA_INFO_CONNECTED_TIME, + NL80211_STA_INFO_STA_FLAGS, ++ NL80211_STA_INFO_CHAIN_SIGNAL, ++ NL80211_STA_INFO_CHAIN_SIGNAL_AVG, + + /* keep last */ + __NL80211_STA_INFO_AFTER_LAST, +--- a/net/wireless/nl80211.c ++++ b/net/wireless/nl80211.c +@@ -2287,6 +2287,33 @@ nla_put_failure: + return false; + } + ++static bool nl80211_put_signal(struct sk_buff *msg, u8 mask, s8 *signal, ++ int id) ++{ ++ void *attr; ++ int i = 0; ++ ++ if (!mask) ++ return true; ++ ++ attr = nla_nest_start(msg, id); ++ if (!attr) ++ goto nla_put_failure; ++ ++ for (i = 0; i < 4; i++) { ++ if (!(mask & BIT(i))) ++ continue; ++ ++ NLA_PUT_U8(msg, i, signal[i]); ++ } ++ ++ nla_nest_end(msg, attr); ++ ++ return true; ++nla_put_failure: ++ return false; ++} ++ + 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 + if (sinfo->filled & STATION_INFO_SIGNAL_AVG) + NLA_PUT_U8(msg, NL80211_STA_INFO_SIGNAL_AVG, + sinfo->signal_avg); ++ if (sinfo->filled & STATION_INFO_CHAIN_SIGNAL) { ++ if (!nl80211_put_signal(msg, sinfo->chains, ++ sinfo->chain_signal, ++ NL80211_STA_INFO_CHAIN_SIGNAL)) ++ goto nla_put_failure; ++ } ++ if (sinfo->filled & STATION_INFO_CHAIN_SIGNAL_AVG) { ++ if (!nl80211_put_signal(msg, sinfo->chains, ++ sinfo->chain_signal_avg, ++ NL80211_STA_INFO_CHAIN_SIGNAL_AVG)) ++ goto nla_put_failure; ++ } + if (sinfo->filled & STATION_INFO_TX_BITRATE) { + if (!nl80211_put_sta_rate(msg, &sinfo->txrate, + 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 + { + struct ieee80211_sub_if_data *sdata = sta->sdata; + struct timespec uptime; ++ int i; + + sinfo->generation = sdata->local->sta_generation; + +@@ -365,6 +366,17 @@ static void sta_set_sinfo(struct sta_inf + sinfo->signal = (s8)sta->last_signal; + sinfo->signal_avg = (s8) -ewma_read(&sta->avg_signal); + } ++ if (sta->chains) { ++ sinfo->filled |= STATION_INFO_CHAIN_SIGNAL | ++ STATION_INFO_CHAIN_SIGNAL_AVG; ++ ++ sinfo->chains = sta->chains; ++ for (i = 0; i < ARRAY_SIZE(sinfo->chain_signal); i++) { ++ sinfo->chain_signal[i] = sta->chain_signal_last[i]; ++ sinfo->chain_signal_avg[i] = ++ (s8) -ewma_read(&sta->chain_signal_avg[i]); ++ } ++ } + + sinfo->txrate.flags = 0; + if (sta->last_tx_rate.flags & IEEE80211_TX_RC_MCS) diff --git a/package/mac80211/patches/552-ath9k_fix_phyerror.patch b/package/mac80211/patches/552-ath9k_fix_phyerror.patch deleted file mode 100644 index 3ef090e721..0000000000 --- a/package/mac80211/patches/552-ath9k_fix_phyerror.patch +++ /dev/null @@ -1,37 +0,0 @@ ---- a/drivers/net/wireless/ath/ath9k/recv.c -+++ b/drivers/net/wireless/ath/ath9k/recv.c -@@ -425,12 +425,9 @@ void ath_rx_cleanup(struct ath_softc *sc - - u32 ath_calcrxfilter(struct ath_softc *sc) - { --#define RX_FILTER_PRESERVE (ATH9K_RX_FILTER_PHYERR | ATH9K_RX_FILTER_PHYRADAR) -- - u32 rfilt; - -- rfilt = (ath9k_hw_getrxfilter(sc->sc_ah) & RX_FILTER_PRESERVE) -- | ATH9K_RX_FILTER_UCAST | ATH9K_RX_FILTER_BCAST -+ rfilt = ATH9K_RX_FILTER_UCAST | ATH9K_RX_FILTER_BCAST - | ATH9K_RX_FILTER_MCAST; - - if (sc->rx.rxfilter & FIF_PROBE_REQ) ---- a/drivers/net/wireless/ath/ath9k/ani.c -+++ b/drivers/net/wireless/ath/ath9k/ani.c -@@ -502,9 +502,6 @@ static void ath9k_ani_reset_old(struct a - ath9k_hw_ani_control(ah, ATH9K_ANI_CCK_WEAK_SIGNAL_THR, - ATH9K_ANI_CCK_WEAK_SIG_THR); - -- ath9k_hw_setrxfilter(ah, ath9k_hw_getrxfilter(ah) | -- ATH9K_RX_FILTER_PHYERR); -- - ath9k_ani_restart(ah); - return; - } -@@ -525,8 +522,6 @@ static void ath9k_ani_reset_old(struct a - ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL, - aniState->firstepLevel); - -- ath9k_hw_setrxfilter(ah, ath9k_hw_getrxfilter(ah) & -- ~ATH9K_RX_FILTER_PHYERR); - ath9k_ani_restart(ah); - - ENABLE_REGWRITE_BUFFER(ah); diff --git a/package/mac80211/patches/561-mac80211_tx_status.patch b/package/mac80211/patches/561-mac80211_tx_status.patch deleted file mode 100644 index 513dd0a6ec..0000000000 --- a/package/mac80211/patches/561-mac80211_tx_status.patch +++ /dev/null @@ -1,96 +0,0 @@ ---- a/include/net/mac80211.h -+++ b/include/net/mac80211.h -@@ -2370,6 +2370,25 @@ static inline int ieee80211_sta_ps_trans - void ieee80211_sta_set_tim(struct ieee80211_sta *sta); - - /** -+ * ieee80211_tx_status_sta - transmit status callback -+ * -+ * Call this function for all transmitted frames after they have been -+ * transmitted. It is permissible to not call this function for -+ * multicast frames but this can affect statistics. -+ * -+ * This function may not be called in IRQ context. Calls to this function -+ * for a single hardware must be synchronized against each other. Calls -+ * to this function, ieee80211_tx_status_ni() and ieee80211_tx_status_irqsafe() -+ * may not be mixed for a single hardware. -+ * -+ * @hw: the hardware the frame was transmitted by -+ * @skb: the frame that was transmitted, owned by mac80211 after this call -+ * @sta: station for which the tx status is provided -+ */ -+void ieee80211_tx_status_sta(struct ieee80211_hw *hw, struct sk_buff *skb, -+ struct ieee80211_sta *sta); -+ -+/** - * ieee80211_tx_status - transmit status callback - * - * Call this function for all transmitted frames after they have been -@@ -2384,8 +2403,11 @@ void ieee80211_sta_set_tim(struct ieee80 - * @hw: the hardware the frame was transmitted by - * @skb: the frame that was transmitted, owned by mac80211 after this call - */ --void ieee80211_tx_status(struct ieee80211_hw *hw, -- struct sk_buff *skb); -+static inline void ieee80211_tx_status(struct ieee80211_hw *hw, -+ struct sk_buff *skb) -+{ -+ ieee80211_tx_status_sta(hw, skb, NULL); -+} - - /** - * ieee80211_tx_status_ni - transmit status callback (in process context) ---- a/net/mac80211/status.c -+++ b/net/mac80211/status.c -@@ -202,7 +202,8 @@ static void ieee80211_set_bar_pending(st - */ - #define STA_LOST_PKT_THRESHOLD 50 - --void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) -+void ieee80211_tx_status_sta(struct ieee80211_hw *hw, struct sk_buff *skb, -+ struct ieee80211_sta *pubsta) - { - struct sk_buff *skb2; - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; -@@ -214,7 +215,7 @@ void ieee80211_tx_status(struct ieee8021 - struct ieee80211_tx_status_rtap_hdr *rthdr; - struct ieee80211_sub_if_data *sdata; - struct net_device *prev_dev = NULL; -- struct sta_info *sta, *tmp; -+ struct sta_info *sta = NULL, *tmp, *tmp2; - int retry_count = -1, i; - int rates_idx = -1; - bool send_to_cooked; -@@ -244,11 +245,19 @@ void ieee80211_tx_status(struct ieee8021 - sband = local->hw.wiphy->bands[info->band]; - fc = hdr->frame_control; - -- for_each_sta_info(local, hdr->addr1, sta, tmp) { -- /* skip wrong virtual interface */ -- if (memcmp(hdr->addr2, sta->sdata->vif.addr, ETH_ALEN)) -- continue; -+ if (!pubsta) { -+ for_each_sta_info(local, hdr->addr1, tmp, tmp2) { -+ /* skip wrong virtual interface */ -+ if (memcmp(hdr->addr2, tmp->sdata->vif.addr, ETH_ALEN)) -+ continue; -+ -+ sta = tmp; -+ } -+ } else { -+ sta = container_of(pubsta, struct sta_info, sta); -+ } - -+ if (sta) { - acked = !!(info->flags & IEEE80211_TX_STAT_ACK); - if (!acked && test_sta_flags(sta, WLAN_STA_PS_STA)) { - /* -@@ -497,7 +506,7 @@ void ieee80211_tx_status(struct ieee8021 - rcu_read_unlock(); - dev_kfree_skb(skb); - } --EXPORT_SYMBOL(ieee80211_tx_status); -+EXPORT_SYMBOL(ieee80211_tx_status_sta); - - void ieee80211_report_low_ack(struct ieee80211_sta *pubsta, u32 num_packets) - { diff --git a/package/mac80211/patches/562-ath9k_tx_status.patch b/package/mac80211/patches/562-ath9k_tx_status.patch deleted file mode 100644 index dfe536ca00..0000000000 --- a/package/mac80211/patches/562-ath9k_tx_status.patch +++ /dev/null @@ -1,121 +0,0 @@ ---- a/drivers/net/wireless/ath/ath9k/xmit.c -+++ b/drivers/net/wireless/ath/ath9k/xmit.c -@@ -50,10 +50,12 @@ static u16 bits_per_symbol[][2] = { - static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq, - struct ath_atx_tid *tid, struct sk_buff *skb); - static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, -- int tx_flags, struct ath_txq *txq); -+ int tx_flags, struct ath_txq *txq, -+ struct ieee80211_sta *sta); - 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, int sendbar, -+ struct ieee80211_sta *sta); - 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, -@@ -172,7 +174,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, -+ 1, NULL); - } else { - ath_tx_send_normal(sc, txq, NULL, skb); - } -@@ -239,7 +242,7 @@ static void ath_tid_drain(struct ath_sof - - if (!bf) { - spin_unlock(&txq->axq_lock); -- ath_tx_complete(sc, skb, ATH_TX_ERROR, txq); -+ ath_tx_complete(sc, skb, ATH_TX_ERROR, txq, NULL); - spin_lock(&txq->axq_lock); - continue; - } -@@ -250,7 +253,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, 0, NULL); - spin_lock(&txq->axq_lock); - } - -@@ -412,7 +415,7 @@ static void ath_tx_complete_aggr(struct - list_move_tail(&bf->list, &bf_head); - - ath_tx_complete_buf(sc, bf, txq, &bf_head, ts, -- 0, 0); -+ 0, 0, NULL); - - bf = bf_next; - } -@@ -520,7 +523,7 @@ static void ath_tx_complete_aggr(struct - } - - ath_tx_complete_buf(sc, bf, txq, &bf_head, ts, -- !txfail, sendbar); -+ !txfail, sendbar, sta); - } else { - /* retry the un-acked ones */ - if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)) { -@@ -540,7 +543,8 @@ static void ath_tx_complete_aggr(struct - - ath_tx_complete_buf(sc, bf, txq, - &bf_head, -- ts, 0, 1); -+ ts, 0, 1, -+ sta); - break; - } - -@@ -1465,7 +1469,8 @@ 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, 0, -+ NULL); - spin_lock_bh(&txq->axq_lock); - } - } -@@ -1970,7 +1975,8 @@ 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) -+ int tx_flags, struct ath_txq *txq, -+ struct ieee80211_sta *sta) - { - struct ieee80211_hw *hw = sc->hw; - struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); -@@ -2028,7 +2034,8 @@ 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, int sendbar, -+ struct ieee80211_sta *sta) - { - struct sk_buff *skb = bf->bf_mpdu; - struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); -@@ -2056,7 +2063,7 @@ static void ath_tx_complete_buf(struct a - complete(&sc->paprd_complete); - } else { - ath_debug_stat_tx(sc, bf, ts, txq, tx_flags); -- ath_tx_complete(sc, skb, tx_flags, txq); -+ ath_tx_complete(sc, skb, tx_flags, txq, sta); - } - /* At this point, skb (bf->bf_mpdu) is consumed...make sure we don't - * accidentally reference it later. -@@ -2145,7 +2152,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, 0, NULL); - } else - ath_tx_complete_aggr(sc, txq, bf, bf_head, ts, txok, true); - diff --git a/package/mac80211/patches/570-ath9k_tx_stop_failure_debug.patch b/package/mac80211/patches/570-ath9k_tx_stop_failure_debug.patch deleted file mode 100644 index 9a57c05947..0000000000 --- a/package/mac80211/patches/570-ath9k_tx_stop_failure_debug.patch +++ /dev/null @@ -1,27 +0,0 @@ ---- a/drivers/net/wireless/ath/ath9k/xmit.c -+++ b/drivers/net/wireless/ath/ath9k/xmit.c -@@ -1512,7 +1512,8 @@ bool ath_drain_all_txq(struct ath_softc - struct ath_hw *ah = sc->sc_ah; - struct ath_common *common = ath9k_hw_common(sc->sc_ah); - struct ath_txq *txq; -- int i, npend = 0; -+ int i; -+ u32 npend = 0; - - if (sc->sc_flags & SC_OP_INVALID) - return true; -@@ -1524,11 +1525,12 @@ bool ath_drain_all_txq(struct ath_softc - if (!ATH_TXQ_SETUP(sc, i)) - continue; - -- npend += ath9k_hw_numtxpending(ah, sc->tx.txq[i].axq_qnum); -+ if (ath9k_hw_numtxpending(ah, sc->tx.txq[i].axq_qnum)) -+ npend |= BIT(i); - } - - if (npend) -- ath_err(common, "Failed to stop TX DMA!\n"); -+ ath_err(common, "Failed to stop TX DMA, queues=%08x!\n", npend); - - for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) { - if (!ATH_TXQ_SETUP(sc, i)) diff --git a/package/mac80211/patches/571-ath9k_reset_debug.patch b/package/mac80211/patches/571-ath9k_reset_debug.patch deleted file mode 100644 index 90e62c2afe..0000000000 --- a/package/mac80211/patches/571-ath9k_reset_debug.patch +++ /dev/null @@ -1,124 +0,0 @@ ---- a/drivers/net/wireless/ath/ath9k/debug.h -+++ b/drivers/net/wireless/ath/ath9k/debug.h -@@ -25,8 +25,10 @@ struct ath_buf; - - #ifdef CONFIG_ATH9K_DEBUGFS - #define TX_STAT_INC(q, c) sc->debug.stats.txstats[q].c++ -+#define RESET_STAT_INC(sc, type) sc->debug.stats.reset[type]++ - #else - #define TX_STAT_INC(q, c) do { } while (0) -+#define RESET_STAT_INC(sc, type) do { } while (0) - #endif - - #ifdef CONFIG_ATH9K_DEBUGFS -@@ -171,10 +173,21 @@ struct ath_rx_stats { - u8 rs_antenna; - }; - -+enum ath_reset_type { -+ RESET_TYPE_BB_HANG, -+ RESET_TYPE_BB_WATCHDOG, -+ RESET_TYPE_FATAL_INT, -+ RESET_TYPE_TX_ERROR, -+ RESET_TYPE_TX_HANG, -+ RESET_TYPE_PLL_HANG, -+ __RESET_TYPE_MAX -+}; -+ - struct ath_stats { - struct ath_interrupt_stats istats; - struct ath_tx_stats txstats[ATH9K_NUM_TX_QUEUES]; - struct ath_rx_stats rxstats; -+ u32 reset[__RESET_TYPE_MAX]; - }; - - #define ATH_DBG_MAX_SAMPLES 10 ---- a/drivers/net/wireless/ath/ath9k/main.c -+++ b/drivers/net/wireless/ath/ath9k/main.c -@@ -679,6 +679,16 @@ void ath9k_tasklet(unsigned long data) - - if ((status & ATH9K_INT_FATAL) || - (status & ATH9K_INT_BB_WATCHDOG)) { -+#ifdef CONFIG_ATH9K_DEBUGFS -+ enum ath_reset_type type; -+ -+ if (status & ATH9K_INT_FATAL) -+ type = RESET_TYPE_FATAL_INT; -+ else -+ type = RESET_TYPE_BB_WATCHDOG; -+ -+ RESET_STAT_INC(sc, type); -+#endif - ieee80211_queue_work(sc->hw, &sc->hw_reset_work); - goto out; - } -@@ -995,8 +1005,10 @@ void ath_hw_check(struct work_struct *wo - ath_dbg(common, ATH_DBG_RESET, "Possible baseband hang, " - "busy=%d (try %d)\n", busy, sc->hw_busy_count + 1); - if (busy >= 99) { -- if (++sc->hw_busy_count >= 3) -+ if (++sc->hw_busy_count >= 3) { -+ RESET_STAT_INC(sc, RESET_TYPE_BB_HANG); - ieee80211_queue_work(sc->hw, &sc->hw_reset_work); -+ } - - } else if (busy >= 0) - sc->hw_busy_count = 0; -@@ -1016,6 +1028,7 @@ static void ath_hw_pll_rx_hang_check(str - /* Rx is hung for more than 500ms. Reset it */ - ath_dbg(common, ATH_DBG_RESET, - "Possible RX hang, resetting"); -+ RESET_STAT_INC(sc, RESET_TYPE_PLL_HANG); - ieee80211_queue_work(sc->hw, &sc->hw_reset_work); - count = 0; - } ---- a/drivers/net/wireless/ath/ath9k/xmit.c -+++ b/drivers/net/wireless/ath/ath9k/xmit.c -@@ -587,8 +587,10 @@ static void ath_tx_complete_aggr(struct - - rcu_read_unlock(); - -- if (needreset) -+ if (needreset) { -+ RESET_STAT_INC(sc, RESET_TYPE_TX_ERROR); - ieee80211_queue_work(sc->hw, &sc->hw_reset_work); -+ } - } - - static bool ath_lookup_legacy(struct ath_buf *bf) -@@ -2270,6 +2272,7 @@ static void ath_tx_complete_poll_work(st - if (needreset) { - ath_dbg(ath9k_hw_common(sc->sc_ah), ATH_DBG_RESET, - "tx hung, resetting the chip\n"); -+ RESET_STAT_INC(sc, RESET_TYPE_TX_HANG); - ieee80211_queue_work(sc->hw, &sc->hw_reset_work); - } - ---- a/drivers/net/wireless/ath/ath9k/debug.c -+++ b/drivers/net/wireless/ath/ath9k/debug.c -@@ -523,9 +523,22 @@ static ssize_t read_file_wiphy(struct fi - if (tmp & ATH9K_RX_FILTER_PHYRADAR) - len += snprintf(buf + len, sizeof(buf) - len, " PHYRADAR"); - if (tmp & ATH9K_RX_FILTER_MCAST_BCAST_ALL) -- len += snprintf(buf + len, sizeof(buf) - len, " MCAST_BCAST_ALL\n"); -- else -- len += snprintf(buf + len, sizeof(buf) - len, "\n"); -+ len += snprintf(buf + len, sizeof(buf) - len, " MCAST_BCAST_ALL"); -+ -+ len += snprintf(buf + len, sizeof(buf) - len, -+ "\n\nReset causes:\n" -+ " baseband hang: %d\n" -+ " baseband watchdog: %d\n" -+ " fatal hardware error interrupt: %d\n" -+ " tx hardware error: %d\n" -+ " tx path hang: %d\n" -+ " pll rx hang: %d\n", -+ sc->debug.stats.reset[RESET_TYPE_BB_HANG], -+ sc->debug.stats.reset[RESET_TYPE_BB_WATCHDOG], -+ sc->debug.stats.reset[RESET_TYPE_FATAL_INT], -+ sc->debug.stats.reset[RESET_TYPE_TX_ERROR], -+ sc->debug.stats.reset[RESET_TYPE_TX_HANG], -+ sc->debug.stats.reset[RESET_TYPE_PLL_HANG]); - - if (len > sizeof(buf)) - len = sizeof(buf); diff --git a/package/mac80211/patches/572-ath9k_fix_tx_retry.patch b/package/mac80211/patches/572-ath9k_fix_tx_retry.patch deleted file mode 100644 index dfb09ba22e..0000000000 --- a/package/mac80211/patches/572-ath9k_fix_tx_retry.patch +++ /dev/null @@ -1,41 +0,0 @@ ---- a/drivers/net/wireless/ath/ath9k/xmit.c -+++ b/drivers/net/wireless/ath/ath9k/xmit.c -@@ -387,7 +387,6 @@ static void ath_tx_complete_aggr(struct - struct ath_frame_info *fi; - int nframes; - u8 tidno; -- bool clear_filter; - int i, retries; - - skb = bf->bf_mpdu; -@@ -484,12 +483,10 @@ static void ath_tx_complete_aggr(struct - */ - txfail = 1; - } else if (fi->retries < ATH_MAX_SW_RETRIES) { -- if (!(ts->ts_status & ATH9K_TXERR_FILT) || -- !an->sleeping) -+ if (txok || !an->sleeping) - ath_tx_set_retry(sc, txq, bf->bf_mpdu, - retries); - -- clear_filter = true; - txpending = 1; - } else { - txfail = 1; -@@ -568,11 +565,13 @@ static void ath_tx_complete_aggr(struct - ieee80211_sta_set_tim(sta); - - spin_lock_bh(&txq->axq_lock); -- if (clear_filter) -- tid->ac->clear_ps_filter = true; - skb_queue_splice(&bf_pending, &tid->buf_q); -- if (!an->sleeping) -+ if (!an->sleeping) { - ath_tx_queue_tid(txq, tid); -+ -+ if (ts->ts_status & ATH9K_TXERR_FILT) -+ tid->ac->clear_ps_filter = true; -+ } - spin_unlock_bh(&txq->axq_lock); - } - diff --git a/package/mac80211/patches/573-ath9k_fix_tx_flush_bar.patch b/package/mac80211/patches/573-ath9k_fix_tx_flush_bar.patch deleted file mode 100644 index a87151bb3a..0000000000 --- a/package/mac80211/patches/573-ath9k_fix_tx_flush_bar.patch +++ /dev/null @@ -1,51 +0,0 @@ ---- a/drivers/net/wireless/ath/ath9k/mac.h -+++ b/drivers/net/wireless/ath/ath9k/mac.h -@@ -75,9 +75,10 @@ - #define ATH9K_TXERR_XTXOP 0x08 - #define ATH9K_TXERR_TIMER_EXPIRED 0x10 - #define ATH9K_TX_ACKED 0x20 -+#define ATH9K_TX_FLUSH 0x40 - #define ATH9K_TXERR_MASK \ - (ATH9K_TXERR_XRETRY | ATH9K_TXERR_FILT | ATH9K_TXERR_FIFO | \ -- ATH9K_TXERR_XTXOP | ATH9K_TXERR_TIMER_EXPIRED) -+ ATH9K_TXERR_XTXOP | ATH9K_TXERR_TIMER_EXPIRED | ATH9K_TX_FLUSH) - - #define ATH9K_TX_BA 0x01 - #define ATH9K_TX_PWRMGMT 0x02 ---- a/drivers/net/wireless/ath/ath9k/xmit.c -+++ b/drivers/net/wireless/ath/ath9k/xmit.c -@@ -388,6 +388,7 @@ static void ath_tx_complete_aggr(struct - int nframes; - u8 tidno; - int i, retries; -+ bool flush = !!(ts->ts_status & ATH9K_TX_FLUSH); - - skb = bf->bf_mpdu; - hdr = (struct ieee80211_hdr *)skb->data; -@@ -482,6 +483,8 @@ static void ath_tx_complete_aggr(struct - * 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, -@@ -540,7 +543,8 @@ static void ath_tx_complete_aggr(struct - - ath_tx_complete_buf(sc, bf, txq, - &bf_head, -- ts, 0, 1, -+ ts, 0, -+ !flush, - sta); - break; - } -@@ -1446,6 +1450,7 @@ static void ath_drain_txq_list(struct at - struct ath_tx_status ts; - - memset(&ts, 0, sizeof(ts)); -+ ts.ts_status = ATH9K_TX_FLUSH; - INIT_LIST_HEAD(&bf_head); - - while (!list_empty(list)) { diff --git a/package/mac80211/patches/580-ath9k_cleanup_set_interrupt.patch b/package/mac80211/patches/580-ath9k_cleanup_set_interrupt.patch deleted file mode 100644 index a93857a19d..0000000000 --- a/package/mac80211/patches/580-ath9k_cleanup_set_interrupt.patch +++ /dev/null @@ -1,155 +0,0 @@ ---- a/drivers/net/wireless/ath/ath9k/beacon.c -+++ b/drivers/net/wireless/ath/ath9k/beacon.c -@@ -515,7 +515,7 @@ static void ath_beacon_config_ap(struct - sc->sc_flags |= SC_OP_TSF_RESET; - ath9k_beacon_init(sc, nexttbtt, intval); - sc->beacon.bmisscnt = 0; -- ath9k_hw_set_interrupts(ah, ah->imask); -+ ath9k_hw_set_interrupts(ah); - ath9k_hw_enable_interrupts(ah); - } - -@@ -643,7 +643,7 @@ static void ath_beacon_config_sta(struct - ath9k_hw_set_sta_beacon_timers(ah, &bs); - ah->imask |= ATH9K_INT_BMISS; - -- ath9k_hw_set_interrupts(ah, ah->imask); -+ ath9k_hw_set_interrupts(ah); - ath9k_hw_enable_interrupts(ah); - } - -@@ -679,7 +679,7 @@ static void ath_beacon_config_adhoc(stru - ath9k_beacon_init(sc, nexttbtt, intval); - sc->beacon.bmisscnt = 0; - -- ath9k_hw_set_interrupts(ah, ah->imask); -+ ath9k_hw_set_interrupts(ah); - ath9k_hw_enable_interrupts(ah); - } - -@@ -821,11 +821,11 @@ void ath9k_set_beaconing_status(struct a - if (status) { - /* Re-enable beaconing */ - ah->imask |= ATH9K_INT_SWBA; -- ath9k_hw_set_interrupts(ah, ah->imask); -+ ath9k_hw_set_interrupts(ah); - } else { - /* Disable SWBA interrupt */ - ah->imask &= ~ATH9K_INT_SWBA; -- ath9k_hw_set_interrupts(ah, ah->imask); -+ ath9k_hw_set_interrupts(ah); - tasklet_kill(&sc->bcon_tasklet); - ath9k_hw_stop_dma_queue(ah, sc->beacon.beaconq); - } ---- a/drivers/net/wireless/ath/ath9k/gpio.c -+++ b/drivers/net/wireless/ath/ath9k/gpio.c -@@ -151,7 +151,7 @@ static void ath9k_gen_timer_start(struct - if ((ah->imask & ATH9K_INT_GENTIMER) == 0) { - ath9k_hw_disable_interrupts(ah); - ah->imask |= ATH9K_INT_GENTIMER; -- ath9k_hw_set_interrupts(ah, ah->imask); -+ ath9k_hw_set_interrupts(ah); - ath9k_hw_enable_interrupts(ah); - } - } -@@ -166,7 +166,7 @@ static void ath9k_gen_timer_stop(struct - if (timer_table->timer_mask.val == 0) { - ath9k_hw_disable_interrupts(ah); - ah->imask &= ~ATH9K_INT_GENTIMER; -- ath9k_hw_set_interrupts(ah, ah->imask); -+ ath9k_hw_set_interrupts(ah); - ath9k_hw_enable_interrupts(ah); - } - } ---- a/drivers/net/wireless/ath/ath9k/main.c -+++ b/drivers/net/wireless/ath/ath9k/main.c -@@ -273,7 +273,7 @@ static bool ath_complete_reset(struct at - - ath9k_cmn_update_txpow(ah, sc->curtxpow, - sc->config.txpowlimit, &sc->curtxpow); -- ath9k_hw_set_interrupts(ah, ah->imask); -+ ath9k_hw_set_interrupts(ah); - ath9k_hw_enable_interrupts(ah); - - if (!(sc->sc_flags & (SC_OP_OFFCHANNEL)) && start) { -@@ -833,7 +833,7 @@ irqreturn_t ath_isr(int irq, void *dev) - - if (status & ATH9K_INT_RXEOL) { - ah->imask &= ~(ATH9K_INT_RXEOL | ATH9K_INT_RXORN); -- ath9k_hw_set_interrupts(ah, ah->imask); -+ ath9k_hw_set_interrupts(ah); - } - - if (status & ATH9K_INT_MIB) { -@@ -1409,7 +1409,7 @@ static void ath9k_calculate_summary_stat - ah->imask &= ~ATH9K_INT_TSFOOR; - } - -- ath9k_hw_set_interrupts(ah, ah->imask); -+ ath9k_hw_set_interrupts(ah); - - /* Set up ANI */ - if (iter_data.naps > 0) { -@@ -1566,7 +1566,7 @@ static void ath9k_enable_ps(struct ath_s - if (!(ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) { - if ((ah->imask & ATH9K_INT_TIM_TIMER) == 0) { - ah->imask |= ATH9K_INT_TIM_TIMER; -- ath9k_hw_set_interrupts(ah, ah->imask); -+ ath9k_hw_set_interrupts(ah); - } - ath9k_hw_setrxabort(ah, 1); - } -@@ -1586,7 +1586,7 @@ static void ath9k_disable_ps(struct ath_ - PS_WAIT_FOR_TX_ACK); - if (ah->imask & ATH9K_INT_TIM_TIMER) { - ah->imask &= ~ATH9K_INT_TIM_TIMER; -- ath9k_hw_set_interrupts(ah, ah->imask); -+ ath9k_hw_set_interrupts(ah); - } - } - ---- a/drivers/net/wireless/ath/ath9k/recv.c -+++ b/drivers/net/wireless/ath/ath9k/recv.c -@@ -1974,7 +1974,7 @@ requeue: - - if (!(ah->imask & ATH9K_INT_RXEOL)) { - ah->imask |= (ATH9K_INT_RXEOL | ATH9K_INT_RXORN); -- ath9k_hw_set_interrupts(ah, ah->imask); -+ ath9k_hw_set_interrupts(ah); - } - - return 0; ---- a/drivers/net/wireless/ath/ath9k/mac.c -+++ b/drivers/net/wireless/ath/ath9k/mac.c -@@ -827,9 +827,9 @@ void ath9k_hw_enable_interrupts(struct a - } - EXPORT_SYMBOL(ath9k_hw_enable_interrupts); - --void ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints) -+void ath9k_hw_set_interrupts(struct ath_hw *ah) - { -- enum ath9k_int omask = ah->imask; -+ enum ath9k_int ints = ah->imask; - u32 mask, mask2; - struct ath9k_hw_capabilities *pCap = &ah->caps; - struct ath_common *common = ath9k_hw_common(ah); -@@ -837,7 +837,7 @@ void ath9k_hw_set_interrupts(struct ath_ - if (!(ints & ATH9K_INT_GLOBAL)) - ath9k_hw_disable_interrupts(ah); - -- ath_dbg(common, ATH_DBG_INTERRUPT, "0x%x => 0x%x\n", omask, ints); -+ ath_dbg(common, ATH_DBG_INTERRUPT, "New interrupt mask 0x%x\n", ints); - - mask = ints & ATH9K_INT_COMMON; - mask2 = 0; ---- a/drivers/net/wireless/ath/ath9k/mac.h -+++ b/drivers/net/wireless/ath/ath9k/mac.h -@@ -735,7 +735,7 @@ int ath9k_hw_beaconq_setup(struct ath_hw - - /* Interrupt Handling */ - bool ath9k_hw_intrpend(struct ath_hw *ah); --void ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints); -+void ath9k_hw_set_interrupts(struct ath_hw *ah); - void ath9k_hw_enable_interrupts(struct ath_hw *ah); - void ath9k_hw_disable_interrupts(struct ath_hw *ah); - diff --git a/package/mac80211/patches/581-ath9k_cleanup_txpower_handling.patch b/package/mac80211/patches/581-ath9k_cleanup_txpower_handling.patch deleted file mode 100644 index 029ce3d7af..0000000000 --- a/package/mac80211/patches/581-ath9k_cleanup_txpower_handling.patch +++ /dev/null @@ -1,627 +0,0 @@ ---- a/drivers/net/wireless/ath/ath.h -+++ b/drivers/net/wireless/ath/ath.h -@@ -71,7 +71,6 @@ struct ath_regulatory { - char alpha2[2]; - u16 country_code; - u16 max_power_level; -- u32 tp_scale; - u16 current_rd; - u16 current_rd_ext; - int16_t power_limit; ---- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c -+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c -@@ -3040,6 +3040,10 @@ static u32 ath9k_hw_ar9300_get_eeprom(st - return (pBase->miscConfiguration >> 0x3) & 0x1; - case EEP_ANT_DIV_CTL1: - return eep->base_ext1.ant_div_control; -+ case EEP_ANTENNA_GAIN_5G: -+ return eep->modalHeader5G.antennaGain; -+ case EEP_ANTENNA_GAIN_2G: -+ return eep->modalHeader2G.antennaGain; - default: - return 0; - } -@@ -4727,20 +4731,14 @@ static u16 ar9003_hw_get_max_edge_power( - static void ar9003_hw_set_power_per_rate_table(struct ath_hw *ah, - struct ath9k_channel *chan, - u8 *pPwrArray, u16 cfgCtl, -- u8 twiceAntennaReduction, -- u8 twiceMaxRegulatoryPower, -+ u8 antenna_reduction, - u16 powerLimit) - { -- struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); - struct ath_common *common = ath9k_hw_common(ah); - struct ar9300_eeprom *pEepData = &ah->eeprom.ar9300_eep; - u16 twiceMaxEdgePower = MAX_RATE_POWER; -- static const u16 tpScaleReductionTable[5] = { -- 0, 3, 6, 9, MAX_RATE_POWER -- }; - int i; -- int16_t twiceLargestAntenna; -- u16 scaledPower = 0, minCtlPower, maxRegAllowedPower; -+ u16 scaledPower = 0, minCtlPower; - static const u16 ctlModesFor11a[] = { - CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40 - }; -@@ -4758,28 +4756,7 @@ static void ar9003_hw_set_power_per_rate - bool is2ghz = IS_CHAN_2GHZ(chan); - - ath9k_hw_get_channel_centers(ah, chan, ¢ers); -- -- /* Compute TxPower reduction due to Antenna Gain */ -- if (is2ghz) -- twiceLargestAntenna = pEepData->modalHeader2G.antennaGain; -- else -- twiceLargestAntenna = pEepData->modalHeader5G.antennaGain; -- -- twiceLargestAntenna = (int16_t)min((twiceAntennaReduction) - -- twiceLargestAntenna, 0); -- -- /* -- * scaledPower is the minimum of the user input power level -- * and the regulatory allowed power level -- */ -- maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna; -- -- if (regulatory->tp_scale != ATH9K_TP_SCALE_MAX) { -- maxRegAllowedPower -= -- (tpScaleReductionTable[(regulatory->tp_scale)] * 2); -- } -- -- scaledPower = min(powerLimit, maxRegAllowedPower); -+ scaledPower = powerLimit - antenna_reduction; - - /* - * Reduce scaled Power by number of chains active to get -@@ -4966,7 +4943,6 @@ static inline u8 mcsidx_to_tgtpwridx(uns - static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah, - struct ath9k_channel *chan, u16 cfgCtl, - u8 twiceAntennaReduction, -- u8 twiceMaxRegulatoryPower, - u8 powerLimit, bool test) - { - struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); -@@ -5019,7 +4995,6 @@ static void ath9k_hw_ar9300_set_txpower( - ar9003_hw_set_power_per_rate_table(ah, chan, - targetPowerValT2, cfgCtl, - twiceAntennaReduction, -- twiceMaxRegulatoryPower, - powerLimit); - - if (ah->eep_ops->get_eeprom(ah, EEP_PAPRD)) { ---- a/drivers/net/wireless/ath/ath9k/hw.c -+++ b/drivers/net/wireless/ath/ath9k/hw.c -@@ -429,7 +429,6 @@ static void ath9k_hw_init_defaults(struc - - regulatory->country_code = CTRY_DEFAULT; - regulatory->power_limit = MAX_RATE_POWER; -- regulatory->tp_scale = ATH9K_TP_SCALE_MAX; - - ah->hw_version.magic = AR5416_MAGIC; - ah->hw_version.subvendorid = 0; -@@ -1396,9 +1395,7 @@ static bool ath9k_hw_chip_reset(struct a - static bool ath9k_hw_channel_change(struct ath_hw *ah, - struct ath9k_channel *chan) - { -- struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); - struct ath_common *common = ath9k_hw_common(ah); -- struct ieee80211_channel *channel = chan->chan; - u32 qnum; - int r; - -@@ -1423,14 +1420,7 @@ static bool ath9k_hw_channel_change(stru - return false; - } - ath9k_hw_set_clockrate(ah); -- -- ah->eep_ops->set_txpower(ah, chan, -- ath9k_regd_get_ctl(regulatory, chan), -- channel->max_antenna_gain * 2, -- channel->max_power * 2, -- min((u32) MAX_RATE_POWER, -- (u32) regulatory->power_limit), false); -- -+ ath9k_hw_apply_txpower(ah, chan); - ath9k_hw_rfbus_done(ah); - - if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan)) -@@ -2466,23 +2456,56 @@ bool ath9k_hw_disable(struct ath_hw *ah) - } - EXPORT_SYMBOL(ath9k_hw_disable); - -+static int get_antenna_gain(struct ath_hw *ah, struct ath9k_channel *chan) -+{ -+ enum eeprom_param gain_param; -+ -+ if (IS_CHAN_2GHZ(chan)) -+ gain_param = EEP_ANTENNA_GAIN_2G; -+ else -+ gain_param = EEP_ANTENNA_GAIN_5G; -+ -+ return ah->eep_ops->get_eeprom(ah, gain_param); -+} -+ -+void ath9k_hw_apply_txpower(struct ath_hw *ah, struct ath9k_channel *chan) -+{ -+ struct ath_regulatory *reg = ath9k_hw_regulatory(ah); -+ struct ieee80211_channel *channel; -+ int chan_pwr, new_pwr, max_gain; -+ int ant_gain, ant_reduction = 0; -+ -+ if (!chan) -+ return; -+ -+ channel = chan->chan; -+ chan_pwr = min_t(int, channel->max_power * 2, MAX_RATE_POWER); -+ new_pwr = min_t(int, chan_pwr, reg->power_limit); -+ max_gain = chan_pwr - new_pwr + channel->max_antenna_gain * 2; -+ -+ ant_gain = get_antenna_gain(ah, chan); -+ if (ant_gain > max_gain) -+ ant_reduction = ant_gain - max_gain; -+ -+ ah->eep_ops->set_txpower(ah, chan, -+ ath9k_regd_get_ctl(reg, chan), -+ ant_reduction, new_pwr, false); -+} -+ - void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit, bool test) - { -- struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); -+ struct ath_regulatory *reg = ath9k_hw_regulatory(ah); - struct ath9k_channel *chan = ah->curchan; - struct ieee80211_channel *channel = chan->chan; -- int reg_pwr = min_t(int, MAX_RATE_POWER, limit); -- int chan_pwr = channel->max_power * 2; - -+ reg->power_limit = min_t(int, limit, MAX_RATE_POWER); - if (test) -- reg_pwr = chan_pwr = MAX_RATE_POWER; -+ channel->max_power = MAX_RATE_POWER / 2; - -- regulatory->power_limit = reg_pwr; -+ ath9k_hw_apply_txpower(ah, chan); - -- ah->eep_ops->set_txpower(ah, chan, -- ath9k_regd_get_ctl(regulatory, chan), -- channel->max_antenna_gain * 2, -- chan_pwr, reg_pwr, test); -+ if (test) -+ channel->max_power = DIV_ROUND_UP(reg->max_power_level, 2); - } - EXPORT_SYMBOL(ath9k_hw_set_txpowerlimit); - ---- a/drivers/net/wireless/ath/ath9k/hw.h -+++ b/drivers/net/wireless/ath/ath9k/hw.h -@@ -389,14 +389,6 @@ enum ath9k_power_mode { - ATH9K_PM_UNDEFINED - }; - --enum ath9k_tp_scale { -- ATH9K_TP_SCALE_MAX = 0, -- ATH9K_TP_SCALE_50, -- ATH9K_TP_SCALE_25, -- ATH9K_TP_SCALE_12, -- ATH9K_TP_SCALE_MIN --}; -- - enum ser_reg_mode { - SER_REG_MODE_OFF = 0, - SER_REG_MODE_ON = 1, -@@ -964,6 +956,7 @@ void ath9k_hw_htc_resetinit(struct ath_h - /* PHY */ - void ath9k_hw_get_delta_slope_vals(struct ath_hw *ah, u32 coef_scaled, - u32 *coef_mantissa, u32 *coef_exponent); -+void ath9k_hw_apply_txpower(struct ath_hw *ah, struct ath9k_channel *chan); - - /* - * Code Specific to AR5008, AR9001 or AR9002, ---- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c -+++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c -@@ -350,6 +350,8 @@ static u32 ath9k_hw_4k_get_eeprom(struct - return pModal->antdiv_ctl1; - case EEP_TXGAIN_TYPE: - return pBase->txGainType; -+ case EEP_ANTENNA_GAIN_2G: -+ return pModal->antennaGainCh[0]; - default: - return 0; - } -@@ -462,8 +464,7 @@ static void ath9k_hw_set_4k_power_per_ra - struct ath9k_channel *chan, - int16_t *ratesArray, - u16 cfgCtl, -- u16 AntennaReduction, -- u16 twiceMaxRegulatoryPower, -+ u16 antenna_reduction, - u16 powerLimit) - { - #define CMP_TEST_GRP \ -@@ -472,20 +473,16 @@ static void ath9k_hw_set_4k_power_per_ra - || (((cfgCtl & ~CTL_MODE_M) | (pCtlMode[ctlMode] & CTL_MODE_M)) == \ - ((pEepData->ctlIndex[i] & CTL_MODE_M) | SD_NO_CTL)) - -- struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); - int i; -- int16_t twiceLargestAntenna; - u16 twiceMinEdgePower; - u16 twiceMaxEdgePower = MAX_RATE_POWER; -- u16 scaledPower = 0, minCtlPower, maxRegAllowedPower; -+ u16 scaledPower = 0, minCtlPower; - u16 numCtlModes; - const u16 *pCtlMode; - u16 ctlMode, freq; - struct chan_centers centers; - struct cal_ctl_data_4k *rep; - struct ar5416_eeprom_4k *pEepData = &ah->eeprom.map4k; -- static const u16 tpScaleReductionTable[5] = -- { 0, 3, 6, 9, MAX_RATE_POWER }; - struct cal_target_power_leg targetPowerOfdm, targetPowerCck = { - 0, { 0, 0, 0, 0} - }; -@@ -503,19 +500,7 @@ static void ath9k_hw_set_4k_power_per_ra - - ath9k_hw_get_channel_centers(ah, chan, ¢ers); - -- twiceLargestAntenna = pEepData->modalHeader.antennaGainCh[0]; -- twiceLargestAntenna = (int16_t)min(AntennaReduction - -- twiceLargestAntenna, 0); -- -- maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna; -- if (regulatory->tp_scale != ATH9K_TP_SCALE_MAX) { -- maxRegAllowedPower -= -- (tpScaleReductionTable[(regulatory->tp_scale)] * 2); -- } -- -- scaledPower = min(powerLimit, maxRegAllowedPower); -- scaledPower = max((u16)0, scaledPower); -- -+ scaledPower = powerLimit - antenna_reduction; - numCtlModes = ARRAY_SIZE(ctlModesFor11g) - SUB_NUM_CTL_MODES_AT_2G_40; - pCtlMode = ctlModesFor11g; - -@@ -671,7 +656,6 @@ static void ath9k_hw_4k_set_txpower(stru - struct ath9k_channel *chan, - u16 cfgCtl, - u8 twiceAntennaReduction, -- u8 twiceMaxRegulatoryPower, - u8 powerLimit, bool test) - { - struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); -@@ -691,7 +675,6 @@ static void ath9k_hw_4k_set_txpower(stru - ath9k_hw_set_4k_power_per_rate_table(ah, chan, - &ratesArray[0], cfgCtl, - twiceAntennaReduction, -- twiceMaxRegulatoryPower, - powerLimit); - - ath9k_hw_set_4k_power_cal_table(ah, chan); ---- a/drivers/net/wireless/ath/ath9k/eeprom_9287.c -+++ b/drivers/net/wireless/ath/ath9k/eeprom_9287.c -@@ -336,6 +336,9 @@ static u32 ath9k_hw_ar9287_get_eeprom(st - return pBase->tempSensSlopePalOn; - else - return 0; -+ case EEP_ANTENNA_GAIN_2G: -+ return max_t(u8, pModal->antennaGainCh[0], -+ pModal->antennaGainCh[1]); - default: - return 0; - } -@@ -554,8 +557,7 @@ static void ath9k_hw_set_ar9287_power_pe - struct ath9k_channel *chan, - int16_t *ratesArray, - u16 cfgCtl, -- u16 AntennaReduction, -- u16 twiceMaxRegulatoryPower, -+ u16 antenna_reduction, - u16 powerLimit) - { - #define CMP_CTL \ -@@ -569,12 +571,8 @@ static void ath9k_hw_set_ar9287_power_pe - #define REDUCE_SCALED_POWER_BY_TWO_CHAIN 6 - #define REDUCE_SCALED_POWER_BY_THREE_CHAIN 10 - -- struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); - u16 twiceMaxEdgePower = MAX_RATE_POWER; -- static const u16 tpScaleReductionTable[5] = -- { 0, 3, 6, 9, MAX_RATE_POWER }; - int i; -- int16_t twiceLargestAntenna; - struct cal_ctl_data_ar9287 *rep; - struct cal_target_power_leg targetPowerOfdm = {0, {0, 0, 0, 0} }, - targetPowerCck = {0, {0, 0, 0, 0} }; -@@ -582,7 +580,7 @@ static void ath9k_hw_set_ar9287_power_pe - targetPowerCckExt = {0, {0, 0, 0, 0} }; - struct cal_target_power_ht targetPowerHt20, - targetPowerHt40 = {0, {0, 0, 0, 0} }; -- u16 scaledPower = 0, minCtlPower, maxRegAllowedPower; -+ u16 scaledPower = 0, minCtlPower; - static const u16 ctlModesFor11g[] = { - CTL_11B, CTL_11G, CTL_2GHT20, - CTL_11B_EXT, CTL_11G_EXT, CTL_2GHT40 -@@ -597,24 +595,7 @@ static void ath9k_hw_set_ar9287_power_pe - tx_chainmask = ah->txchainmask; - - ath9k_hw_get_channel_centers(ah, chan, ¢ers); -- -- /* Compute TxPower reduction due to Antenna Gain */ -- twiceLargestAntenna = max(pEepData->modalHeader.antennaGainCh[0], -- pEepData->modalHeader.antennaGainCh[1]); -- twiceLargestAntenna = (int16_t)min((AntennaReduction) - -- twiceLargestAntenna, 0); -- -- /* -- * scaledPower is the minimum of the user input power level -- * and the regulatory allowed power level. -- */ -- maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna; -- -- if (regulatory->tp_scale != ATH9K_TP_SCALE_MAX) -- maxRegAllowedPower -= -- (tpScaleReductionTable[(regulatory->tp_scale)] * 2); -- -- scaledPower = min(powerLimit, maxRegAllowedPower); -+ scaledPower = powerLimit - antenna_reduction; - - /* - * Reduce scaled Power by number of chains active -@@ -815,7 +796,6 @@ static void ath9k_hw_set_ar9287_power_pe - static void ath9k_hw_ar9287_set_txpower(struct ath_hw *ah, - struct ath9k_channel *chan, u16 cfgCtl, - u8 twiceAntennaReduction, -- u8 twiceMaxRegulatoryPower, - u8 powerLimit, bool test) - { - struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); -@@ -834,7 +814,6 @@ static void ath9k_hw_ar9287_set_txpower( - ath9k_hw_set_ar9287_power_per_rate_table(ah, chan, - &ratesArray[0], cfgCtl, - twiceAntennaReduction, -- twiceMaxRegulatoryPower, - powerLimit); - - ath9k_hw_set_ar9287_power_cal_table(ah, chan); ---- a/drivers/net/wireless/ath/ath9k/eeprom_def.c -+++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c -@@ -400,6 +400,7 @@ static u32 ath9k_hw_def_get_eeprom(struc - struct ar5416_eeprom_def *eep = &ah->eeprom.def; - struct modal_eep_header *pModal = eep->modalHeader; - struct base_eep_header *pBase = &eep->baseEepHeader; -+ int band = 0; - - switch (param) { - case EEP_NFTHRESH_5: -@@ -467,6 +468,14 @@ static u32 ath9k_hw_def_get_eeprom(struc - return pBase->pwr_table_offset; - else - return AR5416_PWR_TABLE_OFFSET_DB; -+ case EEP_ANTENNA_GAIN_2G: -+ band = 1; -+ /* fall through */ -+ case EEP_ANTENNA_GAIN_5G: -+ return max_t(u8, max_t(u8, -+ pModal[band].antennaGainCh[0], -+ pModal[band].antennaGainCh[1]), -+ pModal[band].antennaGainCh[2]); - default: - return 0; - } -@@ -986,21 +995,15 @@ static void ath9k_hw_set_def_power_per_r - struct ath9k_channel *chan, - int16_t *ratesArray, - u16 cfgCtl, -- u16 AntennaReduction, -- u16 twiceMaxRegulatoryPower, -+ u16 antenna_reduction, - u16 powerLimit) - { - #define REDUCE_SCALED_POWER_BY_TWO_CHAIN 6 /* 10*log10(2)*2 */ - #define REDUCE_SCALED_POWER_BY_THREE_CHAIN 9 /* 10*log10(3)*2 */ - -- struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); - struct ar5416_eeprom_def *pEepData = &ah->eeprom.def; - u16 twiceMaxEdgePower = MAX_RATE_POWER; -- static const u16 tpScaleReductionTable[5] = -- { 0, 3, 6, 9, MAX_RATE_POWER }; -- - int i; -- int16_t twiceLargestAntenna; - struct cal_ctl_data *rep; - struct cal_target_power_leg targetPowerOfdm, targetPowerCck = { - 0, { 0, 0, 0, 0} -@@ -1012,7 +1015,7 @@ static void ath9k_hw_set_def_power_per_r - struct cal_target_power_ht targetPowerHt20, targetPowerHt40 = { - 0, {0, 0, 0, 0} - }; -- u16 scaledPower = 0, minCtlPower, maxRegAllowedPower; -+ u16 scaledPower = 0, minCtlPower; - static const u16 ctlModesFor11a[] = { - CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40 - }; -@@ -1031,27 +1034,7 @@ static void ath9k_hw_set_def_power_per_r - - ath9k_hw_get_channel_centers(ah, chan, ¢ers); - -- twiceLargestAntenna = max( -- pEepData->modalHeader -- [IS_CHAN_2GHZ(chan)].antennaGainCh[0], -- pEepData->modalHeader -- [IS_CHAN_2GHZ(chan)].antennaGainCh[1]); -- -- twiceLargestAntenna = max((u8)twiceLargestAntenna, -- pEepData->modalHeader -- [IS_CHAN_2GHZ(chan)].antennaGainCh[2]); -- -- twiceLargestAntenna = (int16_t)min(AntennaReduction - -- twiceLargestAntenna, 0); -- -- maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna; -- -- if (regulatory->tp_scale != ATH9K_TP_SCALE_MAX) { -- maxRegAllowedPower -= -- (tpScaleReductionTable[(regulatory->tp_scale)] * 2); -- } -- -- scaledPower = min(powerLimit, maxRegAllowedPower); -+ scaledPower = powerLimit - antenna_reduction; - - switch (ar5416_get_ntxchains(tx_chainmask)) { - case 1: -@@ -1256,7 +1239,6 @@ static void ath9k_hw_def_set_txpower(str - struct ath9k_channel *chan, - u16 cfgCtl, - u8 twiceAntennaReduction, -- u8 twiceMaxRegulatoryPower, - u8 powerLimit, bool test) - { - #define RT_AR_DELTA(x) (ratesArray[x] - cck_ofdm_delta) -@@ -1278,7 +1260,6 @@ static void ath9k_hw_def_set_txpower(str - ath9k_hw_set_def_power_per_rate_table(ah, chan, - &ratesArray[0], cfgCtl, - twiceAntennaReduction, -- twiceMaxRegulatoryPower, - powerLimit); - - ath9k_hw_set_def_power_cal_table(ah, chan); ---- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c -+++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c -@@ -763,10 +763,8 @@ static void ar5008_hw_set_channel_regs(s - static int ar5008_hw_process_ini(struct ath_hw *ah, - struct ath9k_channel *chan) - { -- struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); - struct ath_common *common = ath9k_hw_common(ah); - int i, regWrites = 0; -- struct ieee80211_channel *channel = chan->chan; - u32 modesIndex, freqIndex; - - switch (chan->chanmode) { -@@ -903,14 +901,7 @@ static int ar5008_hw_process_ini(struct - ar5008_hw_set_channel_regs(ah, chan); - ar5008_hw_init_chain_masks(ah); - ath9k_olc_init(ah); -- -- /* Set TX power */ -- ah->eep_ops->set_txpower(ah, chan, -- ath9k_regd_get_ctl(regulatory, chan), -- channel->max_antenna_gain * 2, -- channel->max_power * 2, -- min((u32) MAX_RATE_POWER, -- (u32) regulatory->power_limit), false); -+ ath9k_hw_apply_txpower(ah, chan); - - /* Write analog registers */ - if (!ath9k_hw_set_rf_regs(ah, chan, freqIndex)) { ---- a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c -+++ b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c -@@ -19,7 +19,6 @@ - - void ar9003_paprd_enable(struct ath_hw *ah, bool val) - { -- struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); - struct ath9k_channel *chan = ah->curchan; - struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; - -@@ -54,13 +53,7 @@ void ar9003_paprd_enable(struct ath_hw * - - if (val) { - ah->paprd_table_write_done = true; -- -- ah->eep_ops->set_txpower(ah, chan, -- ath9k_regd_get_ctl(regulatory, chan), -- chan->chan->max_antenna_gain * 2, -- chan->chan->max_power * 2, -- min((u32) MAX_RATE_POWER, -- (u32) regulatory->power_limit), false); -+ ath9k_hw_apply_txpower(ah, chan); - } - - REG_RMW_FIELD(ah, AR_PHY_PAPRD_CTRL0_B0, ---- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c -+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c -@@ -628,9 +628,7 @@ static void ar9003_hw_prog_ini(struct at - static int ar9003_hw_process_ini(struct ath_hw *ah, - struct ath9k_channel *chan) - { -- struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); - unsigned int regWrites = 0, i; -- struct ieee80211_channel *channel = chan->chan; - u32 modesIndex; - - switch (chan->chanmode) { -@@ -683,14 +681,7 @@ static int ar9003_hw_process_ini(struct - ar9003_hw_override_ini(ah); - ar9003_hw_set_channel_regs(ah, chan); - ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask); -- -- /* Set TX power */ -- ah->eep_ops->set_txpower(ah, chan, -- ath9k_regd_get_ctl(regulatory, chan), -- channel->max_antenna_gain * 2, -- channel->max_power * 2, -- min((u32) MAX_RATE_POWER, -- (u32) regulatory->power_limit), false); -+ ath9k_hw_apply_txpower(ah, chan); - - return 0; - } ---- a/drivers/net/wireless/ath/ath9k/common.c -+++ b/drivers/net/wireless/ath/ath9k/common.c -@@ -161,10 +161,12 @@ EXPORT_SYMBOL(ath9k_cmn_count_streams); - void ath9k_cmn_update_txpow(struct ath_hw *ah, u16 cur_txpow, - u16 new_txpow, u16 *txpower) - { -- if (cur_txpow != new_txpow) { -+ struct ath_regulatory *reg = ath9k_hw_regulatory(ah); -+ -+ if (reg->power_limit != new_txpow) { - ath9k_hw_set_txpowerlimit(ah, new_txpow, false); - /* read back in case value is clamped */ -- *txpower = ath9k_hw_regulatory(ah)->power_limit; -+ *txpower = reg->max_power_level; - } - } - EXPORT_SYMBOL(ath9k_cmn_update_txpow); ---- a/drivers/net/wireless/ath/ath9k/eeprom.h -+++ b/drivers/net/wireless/ath/ath9k/eeprom.h -@@ -253,7 +253,9 @@ enum eeprom_param { - EEP_PAPRD, - EEP_MODAL_VER, - EEP_ANT_DIV_CTL1, -- EEP_CHAIN_MASK_REDUCE -+ EEP_CHAIN_MASK_REDUCE, -+ EEP_ANTENNA_GAIN_2G, -+ EEP_ANTENNA_GAIN_5G - }; - - enum ar5416_rates { -@@ -657,8 +659,7 @@ struct eeprom_ops { - void (*set_addac)(struct ath_hw *hw, struct ath9k_channel *chan); - void (*set_txpower)(struct ath_hw *hw, struct ath9k_channel *chan, - u16 cfgCtl, u8 twiceAntennaReduction, -- u8 twiceMaxRegulatoryPower, u8 powerLimit, -- bool test); -+ u8 powerLimit, bool test); - u16 (*get_spur_channel)(struct ath_hw *ah, u16 i, bool is2GHz); - }; - ---- a/drivers/net/wireless/ath/ath9k/init.c -+++ b/drivers/net/wireless/ath/ath9k/init.c -@@ -626,7 +626,6 @@ static void ath9k_init_band_txpower(stru - struct ieee80211_supported_band *sband; - struct ieee80211_channel *chan; - struct ath_hw *ah = sc->sc_ah; -- struct ath_regulatory *reg = ath9k_hw_regulatory(ah); - int i; - - sband = &sc->sbands[band]; -@@ -635,7 +634,6 @@ static void ath9k_init_band_txpower(stru - ah->curchan = &ah->channels[chan->hw_value]; - ath9k_cmn_update_ichannel(ah->curchan, chan, NL80211_CHAN_HT20); - ath9k_hw_set_txpowerlimit(ah, MAX_RATE_POWER, true); -- chan->max_power = reg->max_power_level / 2; - } - } - diff --git a/package/mac80211/patches/582-ath9k_remove_current_rd_ext.patch b/package/mac80211/patches/582-ath9k_remove_current_rd_ext.patch deleted file mode 100644 index c2f61c2582..0000000000 --- a/package/mac80211/patches/582-ath9k_remove_current_rd_ext.patch +++ /dev/null @@ -1,34 +0,0 @@ ---- a/drivers/net/wireless/ath/ath.h -+++ b/drivers/net/wireless/ath/ath.h -@@ -72,7 +72,6 @@ struct ath_regulatory { - u16 country_code; - u16 max_power_level; - u16 current_rd; -- u16 current_rd_ext; - int16_t power_limit; - struct reg_dmn_pair_mapping *regpair; - }; ---- a/drivers/net/wireless/ath/ath9k/hw.c -+++ b/drivers/net/wireless/ath/ath9k/hw.c -@@ -2047,11 +2047,6 @@ int ath9k_hw_fill_cap_info(struct ath_hw - eeval = ah->eep_ops->get_eeprom(ah, EEP_REG_0); - regulatory->current_rd = eeval; - -- eeval = ah->eep_ops->get_eeprom(ah, EEP_REG_1); -- if (AR_SREV_9285_12_OR_LATER(ah)) -- eeval |= AR9285_RDEXT_DEFAULT; -- regulatory->current_rd_ext = eeval; -- - if (ah->opmode != NL80211_IFTYPE_AP && - ah->hw_version.subvendorid == AR_SUBVENDOR_ID_NEW_A) { - if (regulatory->current_rd == 0x64 || ---- a/drivers/net/wireless/ath/carl9170/main.c -+++ b/drivers/net/wireless/ath/carl9170/main.c -@@ -1912,7 +1912,6 @@ static int carl9170_parse_eeprom(struct - ar->hw->channel_change_time = 80 * 1000; - - regulatory->current_rd = le16_to_cpu(ar->eeprom.reg_domain[0]); -- regulatory->current_rd_ext = le16_to_cpu(ar->eeprom.reg_domain[1]); - - /* second part of wiphy init */ - SET_IEEE80211_PERM_ADDR(ar->hw, ar->eeprom.mac_address); diff --git a/package/mac80211/patches/583-ath9k_remove_eep_reg_1.patch b/package/mac80211/patches/583-ath9k_remove_eep_reg_1.patch deleted file mode 100644 index feaa30d934..0000000000 --- a/package/mac80211/patches/583-ath9k_remove_eep_reg_1.patch +++ /dev/null @@ -1,54 +0,0 @@ ---- a/drivers/net/wireless/ath/ath9k/eeprom_def.c -+++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c -@@ -415,8 +415,6 @@ static u32 ath9k_hw_def_get_eeprom(struc - return get_unaligned_be16(pBase->macAddr + 4); - case EEP_REG_0: - return pBase->regDmn[0]; -- case EEP_REG_1: -- return pBase->regDmn[1]; - case EEP_OP_CAP: - return pBase->deviceCap; - case EEP_OP_MODE: ---- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c -+++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c -@@ -322,8 +322,6 @@ static u32 ath9k_hw_4k_get_eeprom(struct - return get_unaligned_be16(pBase->macAddr + 4); - case EEP_REG_0: - return pBase->regDmn[0]; -- case EEP_REG_1: -- return pBase->regDmn[1]; - case EEP_OP_CAP: - return pBase->deviceCap; - case EEP_OP_MODE: ---- a/drivers/net/wireless/ath/ath9k/eeprom_9287.c -+++ b/drivers/net/wireless/ath/ath9k/eeprom_9287.c -@@ -308,8 +308,6 @@ static u32 ath9k_hw_ar9287_get_eeprom(st - return get_unaligned_be16(pBase->macAddr + 4); - case EEP_REG_0: - return pBase->regDmn[0]; -- case EEP_REG_1: -- return pBase->regDmn[1]; - case EEP_OP_CAP: - return pBase->deviceCap; - case EEP_OP_MODE: ---- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c -+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c -@@ -3014,8 +3014,6 @@ static u32 ath9k_hw_ar9300_get_eeprom(st - return get_unaligned_be16(eep->macAddr + 4); - case EEP_REG_0: - return le16_to_cpu(pBase->regDmn[0]); -- case EEP_REG_1: -- return le16_to_cpu(pBase->regDmn[1]); - case EEP_OP_CAP: - return pBase->deviceCap; - case EEP_OP_MODE: ---- a/drivers/net/wireless/ath/ath9k/eeprom.h -+++ b/drivers/net/wireless/ath/ath9k/eeprom.h -@@ -225,7 +225,6 @@ enum eeprom_param { - EEP_MAC_MID, - EEP_MAC_LSW, - EEP_REG_0, -- EEP_REG_1, - EEP_OP_CAP, - EEP_OP_MODE, - EEP_RF_SILENT, diff --git a/package/mac80211/patches/603-rt2x00-introduce-rt2x00eeprom.patch b/package/mac80211/patches/603-rt2x00-introduce-rt2x00eeprom.patch index e8a9fd45f8..0fb42f9fed 100644 --- a/package/mac80211/patches/603-rt2x00-introduce-rt2x00eeprom.patch +++ b/package/mac80211/patches/603-rt2x00-introduce-rt2x00eeprom.patch @@ -117,7 +117,7 @@ /* * Capabilities -@@ -960,6 +962,11 @@ struct rt2x00_dev { +@@ -961,6 +963,11 @@ struct rt2x00_dev { const struct firmware *fw; /* @@ -239,18 +239,18 @@ .get_entry_state = rt2800pci_get_entry_state, --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c -@@ -1142,6 +1142,10 @@ int rt2x00lib_probe_dev(struct rt2x00_de - INIT_WORK(&rt2x00dev->intf_work, rt2x00lib_intf_scheduled); - INIT_DELAYED_WORK(&rt2x00dev->autowakeup_work, rt2x00lib_autowakeup); +@@ -1145,6 +1145,10 @@ int rt2x00lib_probe_dev(struct rt2x00_de + BIT(NL80211_IFTYPE_MESH_POINT) | + BIT(NL80211_IFTYPE_WDS); + retval = rt2x00lib_load_eeprom_file(rt2x00dev); + if (retval) + goto exit; + /* - * Let the driver probe the device to detect the capabilities. + * Initialize work. */ -@@ -1243,6 +1247,11 @@ void rt2x00lib_remove_dev(struct rt2x00_ +@@ -1261,6 +1265,11 @@ void rt2x00lib_remove_dev(struct rt2x00_ * Free queue structures. */ rt2x00queue_free(rt2x00dev); 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 f607ea17b2..25709b85b1 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 -@@ -574,6 +574,7 @@ CONFIG_RT2X00=y +@@ -567,6 +567,7 @@ CONFIG_RT2X00=y CONFIG_RT2X00_LIB=m CONFIG_RT2800_LIB=m CONFIG_RT2X00_LIB_FIRMWARE=y diff --git a/package/mac80211/patches/605-rt2x00-pci-eeprom.patch b/package/mac80211/patches/605-rt2x00-pci-eeprom.patch new file mode 100644 index 0000000000..088d474092 --- /dev/null +++ b/package/mac80211/patches/605-rt2x00-pci-eeprom.patch @@ -0,0 +1,46 @@ +--- a/drivers/net/wireless/rt2x00/rt2800pci.c ++++ b/drivers/net/wireless/rt2x00/rt2800pci.c +@@ -84,7 +84,7 @@ static void rt2800pci_mcu_status(struct + rt2x00pci_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0); + } + +-static void rt2800pci_read_eeprom_soc(struct rt2x00_dev *rt2x00dev) ++static void rt2800pci_read_eeprom_file(struct rt2x00_dev *rt2x00dev) + { + memcpy(rt2x00dev->eeprom, rt2x00dev->eeprom_file->data, EEPROM_SIZE); + } +@@ -938,8 +938,9 @@ static int rt2800pci_validate_eeprom(str + /* + * Read EEPROM into buffer + */ +- if (rt2x00_is_soc(rt2x00dev)) +- rt2800pci_read_eeprom_soc(rt2x00dev); ++ if (rt2x00_is_soc(rt2x00dev) || ++ test_bit(REQUIRE_EEPROM_FILE, &rt2x00dev->cap_flags)) ++ rt2800pci_read_eeprom_file(rt2x00dev); + else if (rt2800pci_efuse_detect(rt2x00dev)) + rt2800pci_read_eeprom_efuse(rt2x00dev); + else +--- a/drivers/net/wireless/rt2x00/rt2x00pci.c ++++ b/drivers/net/wireless/rt2x00/rt2x00pci.c +@@ -255,6 +255,7 @@ exit: + int rt2x00pci_probe(struct pci_dev *pci_dev, const struct rt2x00_ops *ops) + { + struct ieee80211_hw *hw; ++ struct rt2x00_platform_data *pdata; + struct rt2x00_dev *rt2x00dev; + int retval; + +@@ -299,6 +300,12 @@ int rt2x00pci_probe(struct pci_dev *pci_ + rt2x00dev->irq = pci_dev->irq; + rt2x00dev->name = pci_name(pci_dev); + ++ /* if we get passed the name of a eeprom_file_name, then use this in ++ favour of the eeprom */ ++ pdata = rt2x00dev->dev->platform_data; ++ if (pdata && pdata->eeprom_file_name) ++ set_bit(REQUIRE_EEPROM_FILE, &rt2x00dev->cap_flags); ++ + if (pci_is_pcie(pci_dev)) + rt2x00_set_chip_intf(rt2x00dev, RT2X00_CHIP_INTF_PCIE); + else diff --git a/package/mac80211/patches/700-mwl8k-missing-pci-id-for-WNR854T.patch b/package/mac80211/patches/700-mwl8k-missing-pci-id-for-WNR854T.patch index 9bc8a33990..96baa19637 100644 --- a/package/mac80211/patches/700-mwl8k-missing-pci-id-for-WNR854T.patch +++ b/package/mac80211/patches/700-mwl8k-missing-pci-id-for-WNR854T.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/mwl8k.c +++ b/drivers/net/wireless/mwl8k.c -@@ -5192,6 +5192,7 @@ MODULE_FIRMWARE("mwl8k/fmimage_8366.fw") +@@ -5193,6 +5193,7 @@ MODULE_FIRMWARE("mwl8k/fmimage_8366.fw") MODULE_FIRMWARE(MWL8K_8366_AP_FW(MWL8K_8366_AP_FW_API)); static DEFINE_PCI_DEVICE_TABLE(mwl8k_pci_id_table) = { diff --git a/package/mac80211/patches/800-b43-gpio-mask-module-option.patch b/package/mac80211/patches/800-b43-gpio-mask-module-option.patch index 0ee93fb177..08ac033cc5 100644 --- a/package/mac80211/patches/800-b43-gpio-mask-module-option.patch +++ b/package/mac80211/patches/800-b43-gpio-mask-module-option.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/b43/b43.h +++ b/drivers/net/wireless/b43/b43.h -@@ -753,6 +753,7 @@ struct b43_wldev { +@@ -791,6 +791,7 @@ struct b43_wldev { bool qos_enabled; /* TRUE, if QoS is used. */ bool hwcrypto_enabled; /* TRUE, if HW crypto acceleration is enabled. */ bool use_pio; /* TRUE if next init should use PIO */ @@ -22,7 +22,7 @@ static int modparam_bad_frames_preempt; module_param_named(bad_frames_preempt, modparam_bad_frames_preempt, int, 0444); MODULE_PARM_DESC(bad_frames_preempt, -@@ -2679,10 +2684,10 @@ static int b43_gpio_init(struct b43_wlde +@@ -2686,10 +2691,10 @@ static int b43_gpio_init(struct b43_wlde & ~B43_MACCTL_GPOUTSMSK); b43_write16(dev, B43_MMIO_GPIO_MASK, b43_read16(dev, B43_MMIO_GPIO_MASK) diff --git a/package/mac80211/patches/810-b43_no_pio.patch b/package/mac80211/patches/810-b43_no_pio.patch index 3b242f0136..be899c14d4 100644 --- a/package/mac80211/patches/810-b43_no_pio.patch +++ b/package/mac80211/patches/810-b43_no_pio.patch @@ -11,7 +11,7 @@ b43-$(CONFIG_B43_PCMCIA) += pcmcia.o --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c -@@ -1886,9 +1886,11 @@ static void b43_do_interrupt_thread(stru +@@ -1893,9 +1893,11 @@ static void b43_do_interrupt_thread(stru dma_reason[4], dma_reason[5]); b43err(dev->wl, "This device does not support DMA " "on your system. It will now be switched to PIO.\n"); diff --git a/package/mac80211/patches/820-b43-add-antenna-control.patch b/package/mac80211/patches/820-b43-add-antenna-control.patch new file mode 100644 index 0000000000..fd80824857 --- /dev/null +++ b/package/mac80211/patches/820-b43-add-antenna-control.patch @@ -0,0 +1,131 @@ +--- a/drivers/net/wireless/b43/main.c ++++ b/drivers/net/wireless/b43/main.c +@@ -1535,7 +1535,7 @@ static void b43_write_beacon_template(st + len, ram_offset, shm_size_offset, rate); + + /* Write the PHY TX control parameters. */ +- antenna = B43_ANTENNA_DEFAULT; ++ antenna = dev->tx_antenna; + antenna = b43_antenna_to_phyctl(antenna); + ctl = b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_BEACPHYCTL); + /* We can't send beacons with short preamble. Would get PHY errors. */ +@@ -3052,8 +3052,8 @@ static int b43_chip_init(struct b43_wlde + + /* Select the antennae */ + if (phy->ops->set_rx_antenna) +- phy->ops->set_rx_antenna(dev, B43_ANTENNA_DEFAULT); +- b43_mgmtframe_txantenna(dev, B43_ANTENNA_DEFAULT); ++ phy->ops->set_rx_antenna(dev, dev->rx_antenna); ++ b43_mgmtframe_txantenna(dev, dev->tx_antenna); + + if (phy->type == B43_PHYTYPE_B) { + value16 = b43_read16(dev, 0x005E); +@@ -3782,7 +3782,6 @@ static int b43_op_config(struct ieee8021 + struct b43_wldev *dev; + struct b43_phy *phy; + struct ieee80211_conf *conf = &hw->conf; +- int antenna; + int err = 0; + bool reload_bss = false; + +@@ -3836,11 +3835,9 @@ static int b43_op_config(struct ieee8021 + } + + /* Antennas for RX and management frame TX. */ +- antenna = B43_ANTENNA_DEFAULT; +- b43_mgmtframe_txantenna(dev, antenna); +- antenna = B43_ANTENNA_DEFAULT; ++ b43_mgmtframe_txantenna(dev, dev->tx_antenna); + if (phy->ops->set_rx_antenna) +- phy->ops->set_rx_antenna(dev, antenna); ++ phy->ops->set_rx_antenna(dev, dev->rx_antenna); + + if (wl->radio_enabled != phy->radio_on) { + if (wl->radio_enabled) { +@@ -4910,6 +4907,47 @@ static int b43_op_get_survey(struct ieee + return 0; + } + ++static int b43_op_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant) ++{ ++ struct b43_wl *wl = hw_to_b43_wl(hw); ++ struct b43_wldev *dev = wl->current_dev; ++ ++ if (tx_ant == 1 && rx_ant == 1) { ++ dev->tx_antenna = B43_ANTENNA0; ++ dev->rx_antenna = B43_ANTENNA0; ++ } ++ else if (tx_ant == 2 && rx_ant == 2) { ++ dev->tx_antenna = B43_ANTENNA1; ++ dev->rx_antenna = B43_ANTENNA1; ++ } ++ else if ((tx_ant & 3) == 3 && (rx_ant & 3) == 3) { ++ dev->tx_antenna = B43_ANTENNA_DEFAULT; ++ dev->rx_antenna = B43_ANTENNA_DEFAULT; ++ } ++ else { ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++ ++static int b43_op_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant) ++{ ++ struct b43_wl *wl = hw_to_b43_wl(hw); ++ struct b43_wldev *dev = wl->current_dev; ++ ++ switch (dev->tx_antenna) { ++ case B43_ANTENNA0: ++ *tx_ant = 1; *rx_ant = 1; break; ++ case B43_ANTENNA1: ++ *tx_ant = 2; *rx_ant = 2; break; ++ case B43_ANTENNA_DEFAULT: ++ *tx_ant = 3; *rx_ant = 3; break; ++ } ++ return 0; ++} ++ + static const struct ieee80211_ops b43_hw_ops = { + .tx = b43_op_tx, + .conf_tx = b43_op_conf_tx, +@@ -4931,6 +4969,8 @@ static const struct ieee80211_ops b43_hw + .sw_scan_complete = b43_op_sw_scan_complete_notifier, + .get_survey = b43_op_get_survey, + .rfkill_poll = b43_rfkill_poll, ++ .set_antenna = b43_op_set_antenna, ++ .get_antenna = b43_op_get_antenna, + }; + + /* Hard-reset the chip. Do not call this directly. +@@ -5177,6 +5217,8 @@ static int b43_one_core_attach(struct b4 + if (!wldev) + goto out; + ++ wldev->rx_antenna = B43_ANTENNA_DEFAULT; ++ wldev->tx_antenna = B43_ANTENNA_DEFAULT; + wldev->use_pio = b43_modparam_pio; + wldev->dev = dev; + wldev->wl = wl; +@@ -5264,6 +5306,9 @@ static struct b43_wl *b43_wireless_init( + BIT(NL80211_IFTYPE_WDS) | + BIT(NL80211_IFTYPE_ADHOC); + ++ hw->wiphy->available_antennas_rx = 0x3; ++ hw->wiphy->available_antennas_tx = 0x3; ++ + hw->queues = modparam_qos ? 4 : 1; + wl->mac80211_initially_registered_queues = hw->queues; + hw->max_rates = 2; +--- a/drivers/net/wireless/b43/b43.h ++++ b/drivers/net/wireless/b43/b43.h +@@ -792,6 +792,8 @@ struct b43_wldev { + bool hwcrypto_enabled; /* TRUE, if HW crypto acceleration is enabled. */ + bool use_pio; /* TRUE if next init should use PIO */ + int gpiomask; /* GPIO LED mask as a module parameter */ ++ int rx_antenna; /* Used RX antenna (B43_ANTENNAxxx) */ ++ int tx_antenna; /* Used TX antenna (B43_ANTENNAxxx) */ + + /* PHY/Radio device. */ + struct b43_phy phy; diff --git a/package/mac80211/patches/850-p54spi-lock-fix.patch b/package/mac80211/patches/850-p54spi-lock-fix.patch new file mode 100644 index 0000000000..d19ba61702 --- /dev/null +++ b/package/mac80211/patches/850-p54spi-lock-fix.patch @@ -0,0 +1,10 @@ +--- 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 new file mode 100644 index 0000000000..e974e9ddae --- /dev/null +++ b/package/mac80211/patches/851-p54spi-mutex-fix.patch @@ -0,0 +1,15 @@ +--- 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 new file mode 100644 index 0000000000..f8d36ca049 --- /dev/null +++ b/package/mac80211/patches/852-p54spi-cancel-workqueue-fix.patch @@ -0,0 +1,20 @@ +--- 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) -- 2.30.2