mac80211: update to wireless-testing 2015-03-09
authorFelix Fietkau <nbd@openwrt.org>
Wed, 11 Mar 2015 15:02:47 +0000 (15:02 +0000)
committerFelix Fietkau <nbd@openwrt.org>
Wed, 11 Mar 2015 15:02:47 +0000 (15:02 +0000)
Based on patch by Bryan Forbes <bryan@reigndropsfall.net>

Also update mt76 to update for API changes

Signed-off-by: Felix Fietkau <nbd@openwrt.org>
SVN-Revision: 44655

116 files changed:
package/kernel/mac80211/Makefile
package/kernel/mac80211/patches/000-fix_kconfig.patch
package/kernel/mac80211/patches/001-fix_build.patch
package/kernel/mac80211/patches/003-remove_bogus_modparams.patch
package/kernel/mac80211/patches/004-backports_debugfs_fix.patch [new file with mode: 0644]
package/kernel/mac80211/patches/008-fix_netdev_unregister.patch
package/kernel/mac80211/patches/030-rt2x00_options.patch
package/kernel/mac80211/patches/050-lib80211_option.patch
package/kernel/mac80211/patches/060-no_local_ssb_bcma.patch
package/kernel/mac80211/patches/081-backport-devm_kmemdup.patch
package/kernel/mac80211/patches/082-backport-list_last_entry.patch
package/kernel/mac80211/patches/085-bcma-from-4.1.patch [deleted file]
package/kernel/mac80211/patches/100-revert-cryptoapi-ports.patch [new file with mode: 0644]
package/kernel/mac80211/patches/100-revert_aes_ccm_port.patch [deleted file]
package/kernel/mac80211/patches/110-mac80211_keep_keys_on_stop_ap.patch
package/kernel/mac80211/patches/150-disable_addr_notifier.patch
package/kernel/mac80211/patches/210-ap_scan.patch
package/kernel/mac80211/patches/300-Revert-ath5k-Remove-AHB-bus-support.patch [deleted file]
package/kernel/mac80211/patches/300-mac80211-add-an-intermediate-software-queue-implemen.patch [new file with mode: 0644]
package/kernel/mac80211/patches/301-ath5k-fix-AHB-kconfig-dependency.patch [deleted file]
package/kernel/mac80211/patches/301-mac80211-lock-rate-control.patch [new file with mode: 0644]
package/kernel/mac80211/patches/302-ath9k-add-support-for-reporting-tx-power-to-mac80211.patch [deleted file]
package/kernel/mac80211/patches/302-ath9k-restart-only-triggering-DFS-detector-line.patch [new file with mode: 0644]
package/kernel/mac80211/patches/303-ath10k-add-SURVEY_INFO_IN_USE-for-current-channel-on.patch [deleted file]
package/kernel/mac80211/patches/303-ath9k-add-DFS-support-for-extension-channel.patch [new file with mode: 0644]
package/kernel/mac80211/patches/304-ath9k-Fix-RTC_DERIVED_CLK-usage.patch [deleted file]
package/kernel/mac80211/patches/304-ath9k-allow-40MHz-radar-detection-width.patch [new file with mode: 0644]
package/kernel/mac80211/patches/305-ath5k-channel-change-fix.patch [new file with mode: 0644]
package/kernel/mac80211/patches/305-b43-fix-NULL-pointer-dereference-in-b43_phy_copy.patch [deleted file]
package/kernel/mac80211/patches/306-ath5k-fix-reset-race.patch [new file with mode: 0644]
package/kernel/mac80211/patches/306-ath9k-fix-misc-debugfs-when-not-using-chan-context.patch [deleted file]
package/kernel/mac80211/patches/307-ath9k-fix-regression-in-bssidmask-calculation.patch [deleted file]
package/kernel/mac80211/patches/308-rt2x00-do-not-align-payload-on-modern-H-W.patch [deleted file]
package/kernel/mac80211/patches/309-ath9k-prevent-early-IRQs-from-accessing-hardware.patch [deleted file]
package/kernel/mac80211/patches/310-ath9k-set-ATH_OP_INVALID-before-disabling-hardware.patch [deleted file]
package/kernel/mac80211/patches/311-ath9k-do-not-access-hardware-on-IRQs-during-reset.patch [deleted file]
package/kernel/mac80211/patches/312-mac80211-skip-legacy-rate-mask-handling-for-VHT-rate.patch [deleted file]
package/kernel/mac80211/patches/313-mac80211-minstrel_ht-add-a-small-optimization-to-min.patch [deleted file]
package/kernel/mac80211/patches/314-mac80211-minstrel_ht-move-aggregation-check-to-.get_.patch [deleted file]
package/kernel/mac80211/patches/315-mac80211-add-tx_status_noskb-to-rate_control_ops.patch [deleted file]
package/kernel/mac80211/patches/316-mac80211-minstrel-switch-to-.tx_status_noskb.patch [deleted file]
package/kernel/mac80211/patches/317-mac80211-minstrel_ht-switch-to-.tx_status_noskb.patch [deleted file]
package/kernel/mac80211/patches/318-mac80211-add-ieee80211_tx_status_noskb.patch [deleted file]
package/kernel/mac80211/patches/319-mac80211-minstrel_ht-fix-a-crash-in-rate-sorting.patch [deleted file]
package/kernel/mac80211/patches/320-mac80211-notify-drivers-on-sta-rate-table-changes.patch [deleted file]
package/kernel/mac80211/patches/321-mac80211-add-an-intermediate-software-queue-implemen.patch [deleted file]
package/kernel/mac80211/patches/322-mac80211-add-more-missing-checks-for-VHT-tx-rates.patch [deleted file]
package/kernel/mac80211/patches/323-mac80211-copy-chandef-from-AP-vif-to-VLANs.patch [deleted file]
package/kernel/mac80211/patches/324-ath9k_hw-fix-hardware-queue-allocation.patch [deleted file]
package/kernel/mac80211/patches/325-ath9k-fix-BE-BK-queue-order.patch [deleted file]
package/kernel/mac80211/patches/326-ath5k-fix-hardware-queue-index-assignment.patch [deleted file]
package/kernel/mac80211/patches/327-ath10k-fix-low-TX-rates-when-IBSS-and-HT.patch [deleted file]
package/kernel/mac80211/patches/328-ath10k-send-re-assoc-peer-command-when-NSS-changed.patch [deleted file]
package/kernel/mac80211/patches/329-ath9k-fix-race-condition-in-irq-processing-during-ha.patch [deleted file]
package/kernel/mac80211/patches/330-ath5k-fix-spontaneus-AR5312-freezes.patch [deleted file]
package/kernel/mac80211/patches/331-ath5k-channel-change-fix.patch [deleted file]
package/kernel/mac80211/patches/332-ath5k-fix-reset-race.patch [deleted file]
package/kernel/mac80211/patches/400-ath_move_debug_code.patch
package/kernel/mac80211/patches/401-ath9k_blink_default.patch
package/kernel/mac80211/patches/402-ath_regd_optional.patch
package/kernel/mac80211/patches/404-regd_no_assoc_hints.patch
package/kernel/mac80211/patches/410-ath9k_allow_adhoc_and_ap.patch
package/kernel/mac80211/patches/411-ath5k_allow_adhoc_and_ap.patch
package/kernel/mac80211/patches/440-ath5k_channel_bw_debugfs.patch
package/kernel/mac80211/patches/500-ath9k_eeprom_debugfs.patch
package/kernel/mac80211/patches/501-ath9k_ahb_init.patch
package/kernel/mac80211/patches/510-ath9k_intr_mitigation_tweak.patch
package/kernel/mac80211/patches/511-ath9k_reduce_rxbuf.patch
package/kernel/mac80211/patches/512-ath9k_channelbw_debugfs.patch
package/kernel/mac80211/patches/513-ath9k_add_pci_ids.patch
package/kernel/mac80211/patches/522-mac80211_configure_antenna_gain.patch
package/kernel/mac80211/patches/530-ath9k_extra_leds.patch
package/kernel/mac80211/patches/542-ath9k_debugfs_diag.patch
package/kernel/mac80211/patches/543-ath9k_entropy_from_adc.patch
package/kernel/mac80211/patches/544-ath9k-ar933x-usb-hang-workaround.patch
package/kernel/mac80211/patches/545-ath9k_ani_ws_detect.patch
package/kernel/mac80211/patches/600-0002-rt2x00-rt2800lib-introduce-RT2800_HAS_HIGH_SHARED_ME.patch
package/kernel/mac80211/patches/600-0003-rt2x00-rt2800-serialize-shared-memory-access.patch
package/kernel/mac80211/patches/600-0005-rt2x00-rt2800lib-add-hw_beacon_count-field-to-struct.patch
package/kernel/mac80211/patches/600-0006-rt2x00-rt2800lib-init-additional-beacon-offset-regis.patch
package/kernel/mac80211/patches/600-0007-rt2x00-rt2800lib-fix-max-supported-beacon-count-for-.patch
package/kernel/mac80211/patches/600-0009-rt2x00-rt2800lib-enable-support-for-RT3883.patch
package/kernel/mac80211/patches/600-0010-rt2x00-rt2800lib-add-rf_vals-for-RF3853.patch
package/kernel/mac80211/patches/600-0011-rt2x00-rt2800lib-enable-VCO-calibration-for-RF3853.patch
package/kernel/mac80211/patches/600-0013-rt2x00-rt2800lib-enable-RF3853-support.patch
package/kernel/mac80211/patches/600-0014-rt2x00-rt2800lib-add-MAC-register-initialization-for.patch
package/kernel/mac80211/patches/600-0016-rt2x00-rt2800lib-add-BBP-register-initialization-for.patch
package/kernel/mac80211/patches/600-0017-rt2x00-rt2800lib-add-RFCSR-initialization-for-RT3883.patch
package/kernel/mac80211/patches/600-0019-rt2x00-rt2800lib-force-rf-type-to-RF3853-on-RT3883.patch
package/kernel/mac80211/patches/600-0022-rt2x00-rt2800lib-use-correct-txpower-calculation-fun.patch
package/kernel/mac80211/patches/600-0023-rt2x00-rt2800lib-hardcode-txmixer-gain-values-to-zer.patch
package/kernel/mac80211/patches/600-0026-rt2x00-rt2800lib-use-correct-beacon-count-for-RT3883.patch
package/kernel/mac80211/patches/600-0029-rt2x00-rt2800lib-fix-VGC-setup-for-RT3883.patch
package/kernel/mac80211/patches/600-0030-rt2x00-rt2800lib-fix-EEPROM-LNA-validation-for-RT388.patch
package/kernel/mac80211/patches/600-0032-rt2x00-rt2800lib-enable-RT2800_HAS_HIGH_SHARED_MEM-f.patch
package/kernel/mac80211/patches/603-rt2x00-introduce-rt2x00eeprom.patch
package/kernel/mac80211/patches/608-add_platform_data_mac_addr.patch
package/kernel/mac80211/patches/610-rt2x00-fix-rt3352-ext-pa.patch
package/kernel/mac80211/patches/611-rt2x00-rf_vals-rt3352-xtal20.patch
package/kernel/mac80211/patches/612-rt2x00-make-wmac-loadable-via-OF-on-rt288x-305x-SoC.patch
package/kernel/mac80211/patches/615-rt2x00-fix_20mhz_clk.patch
package/kernel/mac80211/patches/616-rt2x00-support-rt5350.patch
package/kernel/mac80211/patches/619-rt2x00-change-led-polarity-from-OF.patch
package/kernel/mac80211/patches/620-rt2x00-rt3352-rf-id.patch
package/kernel/mac80211/patches/700-mwl8k-missing-pci-id-for-WNR854T.patch
package/kernel/mac80211/patches/801-libertas-configure-sysfs-links.patch
package/kernel/mac80211/patches/802-libertas-set-wireless-macaddr.patch
package/kernel/mac80211/patches/805-b43-gpio-mask-module-option.patch
package/kernel/mac80211/patches/810-b43_no_pio.patch
package/kernel/mac80211/patches/820-b43-add-antenna-control.patch
package/kernel/mac80211/patches/845-b43-only-use-gpio-0-1-for-led.patch
package/kernel/mac80211/patches/910-01-add-support-for-mt7620.patch
package/kernel/mac80211/patches/920-ath10k_allow_fallback_to_board_bin_on_empty_otp_stream.patch
package/kernel/mac80211/patches/921-ath10k_init_devices_synchronously.patch
package/kernel/mac80211/patches/930-ath10k_add_tpt_led_trigger.patch
package/kernel/mt76/Makefile

index f3fe6c7..5434a8a 100644 (file)
@@ -10,11 +10,11 @@ include $(INCLUDE_DIR)/kernel.mk
 
 PKG_NAME:=mac80211
 
-PKG_VERSION:=2014-11-04
+PKG_VERSION:=2015-03-09
 PKG_RELEASE:=1
 PKG_SOURCE_URL:=http://mirror2.openwrt.org/sources
 PKG_BACKPORT_VERSION:=
-PKG_MD5SUM:=d0b64853fb78cfd1d6cb639327811e2a
+PKG_MD5SUM:=6d4b04e4ce8a1f54dabfb04f4709453c
 
 PKG_SOURCE:=compat-wireless-$(PKG_VERSION)$(PKG_BACKPORT_VERSION).tar.bz2
 PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/compat-wireless-$(PKG_VERSION)
index 662608e..3987aae 100644 (file)
@@ -1,16 +1,14 @@
 --- a/kconf/Makefile
 +++ b/kconf/Makefile
-@@ -1,10 +1,10 @@
+@@ -1,9 +1,9 @@
 -CFLAGS=-Wall -Wmissing-prototypes -Wstrict-prototypes -O2 -fomit-frame-pointer
 +CFLAGS=-Wall -Wmissing-prototypes -Wstrict-prototypes -O2 -fomit-frame-pointer -DKBUILD_NO_NLS
  
  LXDIALOG := lxdialog/checklist.o lxdialog/inputbox.o lxdialog/menubox.o lxdialog/textbox.o lxdialog/util.o lxdialog/yesno.o
  
  conf: conf.o zconf.tab.o
--mconf: LDFLAGS = -Wl,--add-needed $(shell ./lxdialog/check-lxdialog.sh -ldflags $(CC))
--mconf: CFLAGS += -DCURSES_LOC="<ncurses.h>" -DLOCALE
-+mconf: LDFLAGS = $(shell ./lxdialog/check-lxdialog.sh -ldflags $(CC))
-+mconf: CFLAGS += -DCURSES_LOC="<ncurses.h>"
- mconf: mconf.o zconf.tab.o $(LXDIALOG)
+-mconf_CFLAGS := $(shell ./lxdialog/check-lxdialog.sh -ccflags) -DLOCALE
++mconf_CFLAGS := $(shell ./lxdialog/check-lxdialog.sh -ccflags)
+ mconf_LDFLAGS := $(shell ./lxdialog/check-lxdialog.sh -ldflags $(CC))
+ mconf: CFLAGS += $(mconf_CFLAGS)
  
- .PHONY: clean
index 3c3efdd..818983e 100644 (file)
@@ -6,7 +6,7 @@
  MAKEFLAGS += --no-print-directory
 -SHELL := /bin/bash
 +SHELL := /usr/bin/env bash
- BACKPORT_PWD := $(shell pwd)
+ BACKPORT_DIR := $(shell pwd)
  
  KMODDIR ?= updates
 @@ -19,6 +19,7 @@ KLIB_BUILD ?= $(KLIB)/build/
@@ -15,7 +15,7 @@
  CONFIG_MD5 := $(shell md5sum $(KERNEL_CONFIG) 2>/dev/null | sed 's/\s.*//')
 +STAMP_KERNEL_CONFIG := .kernel_config_md5_$(CONFIG_MD5)
  
- export KLIB KLIB_BUILD BACKPORT_PWD KMODDIR KMODPATH_ARG
+ export KLIB KLIB_BUILD BACKPORT_DIR KMODDIR KMODPATH_ARG
  
 @@ -36,7 +37,8 @@ mrproper:
        @rm -f .kernel_config_md5 Kconfig.versions Kconfig.kernel
@@ -64,7 +64,7 @@
 -              print=0                                                                 ;\
 -              for v in $$kvers ; do                                                   \
 -                      if [ "$$print" = "1" ] ; then                                   \
--                              echo config BACKPORT_KERNEL_$$(echo $$v | tr . _)       ;\
+-                              echo config KERNEL_$$(echo $$v | tr . _)        ;\
 -                              echo "    def_bool y"                                   ;\
 -                      fi                                                              ;\
 -                      if [ "$$v" = "$$kver" ] ; then print=1 ; fi                     ;\
 +      print=0                                                                 ;\
 +      for v in $$kvers ; do                                                   \
 +              if [ "$$print" = "1" ] ; then                                   \
-+                      echo config BACKPORT_KERNEL_$$(echo $$v | tr . _)       ;\
++                      echo config KERNEL_$$(echo $$v | tr . _)        ;\
 +                      echo "    def_bool y"                                   ;\
 +              fi                                                              ;\
 +              if [ "$$v" = "$$kver" ] ; then print=1 ; fi                     ;\
index ffb730b..8fa465a 100644 (file)
@@ -1,31 +1,31 @@
 --- a/compat/main.c
 +++ b/compat/main.c
 @@ -20,31 +20,6 @@ MODULE_LICENSE("GPL");
- #error "You need a BACKPORTS_VERSION"
+ #error "You need a CPTCFG_VERSION"
  #endif
  
--static char *backported_kernel_name = BACKPORTED_KERNEL_NAME;
+-static char *backported_kernel_name = CPTCFG_KERNEL_NAME;
 -
 -module_param(backported_kernel_name, charp, 0400);
 -MODULE_PARM_DESC(backported_kernel_name,
--               "The kernel tree name that was used for this backport (" BACKPORTED_KERNEL_NAME ")");
+-               "The kernel tree name that was used for this backport (" CPTCFG_KERNEL_NAME ")");
 -
--#ifdef BACKPORTS_GIT_TRACKED 
+-#ifdef BACKPORTS_GIT_TRACKED
 -static char *backports_tracker_id = BACKPORTS_GIT_TRACKED;
 -module_param(backports_tracker_id, charp, 0400);
 -MODULE_PARM_DESC(backports_tracker_id,
 -               "The version of the tree containing this backport (" BACKPORTS_GIT_TRACKED ")");
 -#else
--static char *backported_kernel_version = BACKPORTED_KERNEL_VERSION;
--static char *backports_version = BACKPORTS_VERSION;
+-static char *backported_kernel_version = CPTCFG_KERNEL_VERSION;
+-static char *backports_version = CPTCFG_VERSION;
 -
 -module_param(backported_kernel_version, charp, 0400);
 -MODULE_PARM_DESC(backported_kernel_version,
--               "The kernel version that was used for this backport (" BACKPORTED_KERNEL_VERSION ")");
+-               "The kernel version that was used for this backport (" CPTCFG_KERNEL_VERSION ")");
 -
 -module_param(backports_version, charp, 0400);
 -MODULE_PARM_DESC(backports_version,
--               "The git version of the backports tree used to generate this backport (" BACKPORTS_VERSION ")");
+-               "The git version of the backports tree used to generate this backport (" CPTCFG_VERSION ")");
 -
 -#endif
 -
diff --git a/package/kernel/mac80211/patches/004-backports_debugfs_fix.patch b/package/kernel/mac80211/patches/004-backports_debugfs_fix.patch
new file mode 100644 (file)
index 0000000..d48a723
--- /dev/null
@@ -0,0 +1,10 @@
+--- a/backport-include/linux/debugfs.h
++++ b/backport-include/linux/debugfs.h
+@@ -3,6 +3,7 @@
+ #include_next <linux/debugfs.h>
+ #include <linux/version.h>
+ #include <generated/utsrelease.h>
++#include <linux/device.h>
+ #if defined(CONFIG_DEBUG_FS)
+ struct dentry *debugfs_create_devm_seqfile(struct device *dev, const char *name,
index ab39a0a..e07f323 100644 (file)
@@ -1,6 +1,6 @@
 --- a/net/mac80211/iface.c
 +++ b/net/mac80211/iface.c
-@@ -1859,6 +1859,13 @@ void ieee80211_remove_interfaces(struct 
+@@ -1858,6 +1858,13 @@ void ieee80211_remove_interfaces(struct
        }
        mutex_unlock(&local->iflist_mtx);
        unregister_netdevice_many(&unreg_list);
index 5ee52a2..35b5b5d 100644 (file)
@@ -43,5 +43,5 @@
 -      tristate
 +      tristate "RT2x00 support"
        depends on m
-       select BACKPORT_AVERAGE
+       select BPAUTO_AVERAGE
  
index 64e4efb..5fe5558 100644 (file)
@@ -1,7 +1,7 @@
 --- a/net/wireless/Kconfig
 +++ b/net/wireless/Kconfig
-@@ -166,7 +166,7 @@ config CFG80211_WEXT
-         extensions with cfg80211-based drivers.
+@@ -174,7 +174,7 @@ config CFG80211_WEXT_EXPORT
+         wext compatibility symbols to be exported.
  
  config LIB80211
 -      tristate
@@ -9,7 +9,7 @@
        depends on m
        default n
        help
-@@ -176,15 +176,15 @@ config LIB80211
+@@ -184,15 +184,15 @@ config LIB80211
          Drivers should select this themselves if needed.
  
  config LIB80211_CRYPT_WEP
index cd6e31f..d307949 100644 (file)
@@ -1,6 +1,6 @@
 --- a/.local-symbols
 +++ b/.local-symbols
-@@ -423,42 +423,6 @@ USB_CDC_PHONET=
+@@ -344,40 +344,3 @@ USB_CDC_PHONET=
  USB_IPHETH=
  USB_SIERRA_NET=
  USB_VL600=
 -BCMA_HOST_PCI=
 -BCMA_DRIVER_PCI_HOSTMODE=
 -BCMA_HOST_SOC=
+-BCMA_DRIVER_PCI=
 -BCMA_DRIVER_MIPS=
 -BCMA_SFLASH=
 -BCMA_NFLASH=
 -BCMA_DRIVER_GMAC_CMN=
 -BCMA_DRIVER_GPIO=
 -BCMA_DEBUG=
- NFC=
- NFC_DIGITAL=
- NFC_NCI=
---- a/Kconfig
-+++ b/Kconfig
-@@ -33,9 +33,6 @@ source drivers/net/wireless/Kconfig
- source drivers/net/ethernet/Kconfig
- source drivers/net/usb/Kconfig
--source drivers/ssb/Kconfig
--source drivers/bcma/Kconfig
--
- source net/nfc/Kconfig
- source drivers/media/Kconfig
 --- a/Makefile.kernel
 +++ b/Makefile.kernel
-@@ -25,8 +25,6 @@ obj-$(CPTCFG_MAC80211) += net/mac80211/
+@@ -38,8 +38,6 @@ obj-$(CPTCFG_MAC80211) += net/mac80211/
  obj-$(CPTCFG_WLAN) += drivers/net/wireless/
- obj-$(CPTCFG_BT) += net/bluetooth/
- obj-$(CPTCFG_BT) += drivers/bluetooth/
#obj-$(CPTCFG_BT) += net/bluetooth/
#obj-$(CPTCFG_BT) += drivers/bluetooth/
 -obj-$(CPTCFG_SSB) += drivers/ssb/
 -obj-$(CPTCFG_BCMA) += drivers/bcma/
- obj-$(CPTCFG_ETHERNET) += drivers/net/ethernet/
#obj-$(CPTCFG_ETHERNET) += drivers/net/ethernet/
  obj-$(CPTCFG_USB_NET_RNDIS_WLAN) += drivers/net/usb/
- obj-$(CPTCFG_NFC) += net/nfc/
#obj-$(CPTCFG_NFC) += net/nfc/
 --- a/drivers/net/wireless/b43/main.c
 +++ b/drivers/net/wireless/b43/main.c
-@@ -2828,7 +2828,7 @@ static struct ssb_device *b43_ssb_gpio_d
+@@ -2866,7 +2866,7 @@ static struct ssb_device *b43_ssb_gpio_d
  {
        struct ssb_bus *bus = dev->dev->sdev->bus;
  
@@ -77,7 +63,7 @@
        return (bus->chipco.dev ? bus->chipco.dev : bus->pcicore.dev);
  #else
        return bus->chipco.dev;
-@@ -4858,7 +4858,7 @@ static int b43_wireless_core_init(struct
+@@ -4907,7 +4907,7 @@ static int b43_wireless_core_init(struct
        }
        if (sprom->boardflags_lo & B43_BFL_XTAL_NOSLOW)
                hf |= B43_HF_DSCRQ; /* Disable slowclock requests from ucode. */
  void brcms_led_unregister(struct brcms_info *wl);
  int brcms_led_register(struct brcms_info *wl);
  #else
+--- a/Kconfig.sources
++++ b/Kconfig.sources
+@@ -9,9 +9,6 @@ source "$BACKPORT_DIR/drivers/net/wirele
+ #source "$BACKPORT_DIR/drivers/net/ethernet/Kconfig"
+ source "$BACKPORT_DIR/drivers/net/usb/Kconfig"
+-source "$BACKPORT_DIR/drivers/ssb/Kconfig"
+-source "$BACKPORT_DIR/drivers/bcma/Kconfig"
+-
+ #source "$BACKPORT_DIR/net/nfc/Kconfig"
+ #source "$BACKPORT_DIR/drivers/media/Kconfig"
index fb61625..d635ee1 100644 (file)
@@ -1,9 +1,9 @@
 --- a/backport-include/linux/device.h
 +++ b/backport-include/linux/device.h
-@@ -177,4 +177,20 @@ static inline void *devm_kmalloc_array(s
- }
+@@ -200,4 +200,20 @@ static inline void *devm_kmemdup(struct
  #endif
  
 +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0)
 +#define devm_kmemdup LINUX_BACKPORT(devm_kmemdup)
 +static inline void *devm_kmemdup(struct device *dev, const void *src,
index 4ee9047..7e720e0 100644 (file)
@@ -1,8 +1,8 @@
 --- a/backport-include/linux/list.h
 +++ b/backport-include/linux/list.h
-@@ -73,4 +73,17 @@
-       list_entry((pos)->member.next, typeof(*(pos)), member)
- #endif /* list_next_entry */
+@@ -88,4 +88,17 @@
+       list_entry((ptr)->prev, type, member)
+ #endif
  
 +#ifndef list_last_entry
 +/**
diff --git a/package/kernel/mac80211/patches/085-bcma-from-4.1.patch b/package/kernel/mac80211/patches/085-bcma-from-4.1.patch
deleted file mode 100644 (file)
index 6e65950..0000000
+++ /dev/null
@@ -1,318 +0,0 @@
---- a/drivers/bcma/bcma_private.h
-+++ b/drivers/bcma/bcma_private.h
-@@ -41,6 +41,7 @@ int __init bcma_bus_scan_early(struct bc
-                              struct bcma_device_id *match,
-                              struct bcma_device *core);
- void bcma_init_bus(struct bcma_bus *bus);
-+void bcma_unregister_cores(struct bcma_bus *bus);
- /* sprom.c */
- int bcma_sprom_get(struct bcma_bus *bus);
-@@ -105,6 +106,11 @@ static inline void __exit bcma_host_soc_
- /* driver_pci.c */
- u32 bcma_pcie_read(struct bcma_drv_pci *pc, u32 address);
-+void bcma_core_pci_up(struct bcma_drv_pci *pc);
-+void bcma_core_pci_down(struct bcma_drv_pci *pc);
-+
-+/* driver_pcie2.c */
-+void bcma_core_pcie2_up(struct bcma_drv_pcie2 *pcie2);
- extern int bcma_chipco_watchdog_register(struct bcma_drv_cc *cc);
---- a/drivers/bcma/driver_gpio.c
-+++ b/drivers/bcma/driver_gpio.c
-@@ -76,7 +76,7 @@ static void bcma_gpio_free(struct gpio_c
-       bcma_chipco_gpio_pullup(cc, 1 << gpio, 0);
- }
--#if IS_BUILTIN(CONFIG_BCM47XX)
-+#if IS_BUILTIN(CONFIG_BCM47XX) || IS_BUILTIN(CONFIG_ARCH_BCM_5301X)
- static int bcma_gpio_to_irq(struct gpio_chip *chip, unsigned gpio)
- {
-       struct bcma_drv_cc *cc = bcma_gpio_get_cc(chip);
-@@ -215,7 +215,7 @@ int bcma_gpio_init(struct bcma_drv_cc *c
-       chip->set               = bcma_gpio_set_value;
-       chip->direction_input   = bcma_gpio_direction_input;
-       chip->direction_output  = bcma_gpio_direction_output;
--#if IS_BUILTIN(CONFIG_BCM47XX)
-+#if IS_BUILTIN(CONFIG_BCM47XX) || IS_BUILTIN(CONFIG_ARCH_BCM_5301X)
-       chip->to_irq            = bcma_gpio_to_irq;
- #endif
- #if IS_BUILTIN(CONFIG_OF)
---- a/drivers/bcma/driver_pci.c
-+++ b/drivers/bcma/driver_pci.c
-@@ -262,21 +262,21 @@ void bcma_core_pci_power_save(struct bcm
- }
- EXPORT_SYMBOL_GPL(bcma_core_pci_power_save);
--int bcma_core_pci_irq_ctl(struct bcma_drv_pci *pc, struct bcma_device *core,
-+int bcma_core_pci_irq_ctl(struct bcma_bus *bus, struct bcma_device *core,
-                         bool enable)
- {
-       struct pci_dev *pdev;
-       u32 coremask, tmp;
-       int err = 0;
--      if (!pc || core->bus->hosttype != BCMA_HOSTTYPE_PCI) {
-+      if (bus->hosttype != BCMA_HOSTTYPE_PCI) {
-               /* This bcma device is not on a PCI host-bus. So the IRQs are
-                * not routed through the PCI core.
-                * So we must not enable routing through the PCI core. */
-               goto out;
-       }
--      pdev = pc->core->bus->host_pci;
-+      pdev = bus->host_pci;
-       err = pci_read_config_dword(pdev, BCMA_PCI_IRQMASK, &tmp);
-       if (err)
-@@ -308,28 +308,12 @@ static void bcma_core_pci_extend_L1timer
-       bcma_pcie_read(pc, BCMA_CORE_PCI_DLLP_PMTHRESHREG);
- }
--void bcma_core_pci_up(struct bcma_bus *bus)
-+void bcma_core_pci_up(struct bcma_drv_pci *pc)
- {
--      struct bcma_drv_pci *pc;
--
--      if (bus->hosttype != BCMA_HOSTTYPE_PCI)
--              return;
--
--      pc = &bus->drv_pci[0];
--
-       bcma_core_pci_extend_L1timer(pc, true);
- }
--EXPORT_SYMBOL_GPL(bcma_core_pci_up);
--void bcma_core_pci_down(struct bcma_bus *bus)
-+void bcma_core_pci_down(struct bcma_drv_pci *pc)
- {
--      struct bcma_drv_pci *pc;
--
--      if (bus->hosttype != BCMA_HOSTTYPE_PCI)
--              return;
--
--      pc = &bus->drv_pci[0];
--
-       bcma_core_pci_extend_L1timer(pc, false);
- }
--EXPORT_SYMBOL_GPL(bcma_core_pci_down);
---- a/drivers/bcma/driver_pci_host.c
-+++ b/drivers/bcma/driver_pci_host.c
-@@ -11,6 +11,7 @@
- #include "bcma_private.h"
- #include <linux/pci.h>
-+#include <linux/slab.h>
- #include <linux/export.h>
- #include <linux/bcma/bcma.h>
- #include <asm/paccess.h>
---- a/drivers/bcma/driver_pcie2.c
-+++ b/drivers/bcma/driver_pcie2.c
-@@ -10,6 +10,7 @@
- #include "bcma_private.h"
- #include <linux/bcma/bcma.h>
-+#include <linux/pci.h>
- /**************************************************
-  * R/W ops.
-@@ -156,14 +157,23 @@ static void pciedev_reg_pm_clk_period(st
- void bcma_core_pcie2_init(struct bcma_drv_pcie2 *pcie2)
- {
--      struct bcma_chipinfo *ci = &pcie2->core->bus->chipinfo;
-+      struct bcma_bus *bus = pcie2->core->bus;
-+      struct bcma_chipinfo *ci = &bus->chipinfo;
-       u32 tmp;
-       tmp = pcie2_read32(pcie2, BCMA_CORE_PCIE2_SPROM(54));
-       if ((tmp & 0xe) >> 1 == 2)
-               bcma_core_pcie2_cfg_write(pcie2, 0x4e0, 0x17);
--      /* TODO: Do we need pcie_reqsize? */
-+      switch (bus->chipinfo.id) {
-+      case BCMA_CHIP_ID_BCM4360:
-+      case BCMA_CHIP_ID_BCM4352:
-+              pcie2->reqsize = 1024;
-+              break;
-+      default:
-+              pcie2->reqsize = 128;
-+              break;
-+      }
-       if (ci->id == BCMA_CHIP_ID_BCM4360 && ci->rev > 3)
-               bcma_core_pcie2_war_delay_perst_enab(pcie2, true);
-@@ -173,3 +183,18 @@ void bcma_core_pcie2_init(struct bcma_dr
-       pciedev_crwlpciegen2_180(pcie2);
-       pciedev_crwlpciegen2_182(pcie2);
- }
-+
-+/**************************************************
-+ * Runtime ops.
-+ **************************************************/
-+
-+void bcma_core_pcie2_up(struct bcma_drv_pcie2 *pcie2)
-+{
-+      struct bcma_bus *bus = pcie2->core->bus;
-+      struct pci_dev *dev = bus->host_pci;
-+      int err;
-+
-+      err = pcie_set_readrq(dev, pcie2->reqsize);
-+      if (err)
-+              bcma_err(bus, "Error setting PCI_EXP_DEVCTL_READRQ: %d\n", err);
-+}
---- a/drivers/bcma/host_pci.c
-+++ b/drivers/bcma/host_pci.c
-@@ -211,16 +211,26 @@ static int bcma_host_pci_probe(struct pc
-       /* Initialize struct, detect chip */
-       bcma_init_bus(bus);
-+      /* Scan bus to find out generation of PCIe core */
-+      err = bcma_bus_scan(bus);
-+      if (err)
-+              goto err_pci_unmap_mmio;
-+
-+      if (bcma_find_core(bus, BCMA_CORE_PCIE2))
-+              bus->host_is_pcie2 = true;
-+
-       /* Register */
-       err = bcma_bus_register(bus);
-       if (err)
--              goto err_pci_unmap_mmio;
-+              goto err_unregister_cores;
-       pci_set_drvdata(dev, bus);
- out:
-       return err;
-+err_unregister_cores:
-+      bcma_unregister_cores(bus);
- err_pci_unmap_mmio:
-       pci_iounmap(dev, bus->mmio);
- err_pci_release_regions:
-@@ -281,9 +291,12 @@ static const struct pci_device_id bcma_p
-       { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4357) },
-       { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4358) },
-       { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4359) },
-+      { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4360) },
-       { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4365) },
-+      { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x43a0) },
-       { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x43a9) },
-       { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x43aa) },
-+      { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x43b1) },
-       { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4727) },
-       { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 43227) },  /* 0xa8db, BCM43217 (sic!) */
-       { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 43228) },  /* 0xa8dc */
-@@ -308,3 +321,31 @@ void __exit bcma_host_pci_exit(void)
- {
-       pci_unregister_driver(&bcma_pci_bridge_driver);
- }
-+
-+/**************************************************
-+ * Runtime ops for drivers.
-+ **************************************************/
-+
-+/* See also pcicore_up */
-+void bcma_host_pci_up(struct bcma_bus *bus)
-+{
-+      if (bus->hosttype != BCMA_HOSTTYPE_PCI)
-+              return;
-+
-+      if (bus->host_is_pcie2)
-+              bcma_core_pcie2_up(&bus->drv_pcie2);
-+      else
-+              bcma_core_pci_up(&bus->drv_pci[0]);
-+}
-+EXPORT_SYMBOL_GPL(bcma_host_pci_up);
-+
-+/* See also pcicore_down */
-+void bcma_host_pci_down(struct bcma_bus *bus)
-+{
-+      if (bus->hosttype != BCMA_HOSTTYPE_PCI)
-+              return;
-+
-+      if (!bus->host_is_pcie2)
-+              bcma_core_pci_down(&bus->drv_pci[0]);
-+}
-+EXPORT_SYMBOL_GPL(bcma_host_pci_down);
---- a/drivers/bcma/main.c
-+++ b/drivers/bcma/main.c
-@@ -288,7 +288,7 @@ static int bcma_register_devices(struct
-       return 0;
- }
--static void bcma_unregister_cores(struct bcma_bus *bus)
-+void bcma_unregister_cores(struct bcma_bus *bus)
- {
-       struct bcma_device *core, *tmp;
---- a/drivers/net/wireless/b43/main.c
-+++ b/drivers/net/wireless/b43/main.c
-@@ -4770,7 +4770,7 @@ static void b43_wireless_core_exit(struc
-       switch (dev->dev->bus_type) {
- #ifdef CPTCFG_B43_BCMA
-       case B43_BUS_BCMA:
--              bcma_core_pci_down(dev->dev->bdev->bus);
-+              bcma_host_pci_down(dev->dev->bdev->bus);
-               break;
- #endif
- #ifdef CPTCFG_B43_SSB
-@@ -4817,9 +4817,9 @@ static int b43_wireless_core_init(struct
-       switch (dev->dev->bus_type) {
- #ifdef CPTCFG_B43_BCMA
-       case B43_BUS_BCMA:
--              bcma_core_pci_irq_ctl(&dev->dev->bdev->bus->drv_pci[0],
-+              bcma_core_pci_irq_ctl(dev->dev->bdev->bus,
-                                     dev->dev->bdev, true);
--              bcma_core_pci_up(dev->dev->bdev->bus);
-+              bcma_host_pci_up(dev->dev->bdev->bus);
-               break;
- #endif
- #ifdef CPTCFG_B43_SSB
---- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
-+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
-@@ -4669,7 +4669,7 @@ static int brcms_b_attach(struct brcms_c
-       brcms_c_coredisable(wlc_hw);
-       /* Match driver "down" state */
--      bcma_core_pci_down(wlc_hw->d11core->bus);
-+      bcma_host_pci_down(wlc_hw->d11core->bus);
-       /* turn off pll and xtal to match driver "down" state */
-       brcms_b_xtal(wlc_hw, OFF);
-@@ -4960,7 +4960,7 @@ static int brcms_b_up_prep(struct brcms_
-        * Configure pci/pcmcia here instead of in brcms_c_attach()
-        * to allow mfg hotswap:  down, hotswap (chip power cycle), up.
-        */
--      bcma_core_pci_irq_ctl(&wlc_hw->d11core->bus->drv_pci[0], wlc_hw->d11core,
-+      bcma_core_pci_irq_ctl(wlc_hw->d11core->bus, wlc_hw->d11core,
-                             true);
-       /*
-@@ -4970,12 +4970,12 @@ static int brcms_b_up_prep(struct brcms_
-        */
-       if (brcms_b_radio_read_hwdisabled(wlc_hw)) {
-               /* put SB PCI in down state again */
--              bcma_core_pci_down(wlc_hw->d11core->bus);
-+              bcma_host_pci_down(wlc_hw->d11core->bus);
-               brcms_b_xtal(wlc_hw, OFF);
-               return -ENOMEDIUM;
-       }
--      bcma_core_pci_up(wlc_hw->d11core->bus);
-+      bcma_host_pci_up(wlc_hw->d11core->bus);
-       /* reset the d11 core */
-       brcms_b_corereset(wlc_hw, BRCMS_USE_COREFLAGS);
-@@ -5172,7 +5172,7 @@ static int brcms_b_down_finish(struct br
-               /* turn off primary xtal and pll */
-               if (!wlc_hw->noreset) {
--                      bcma_core_pci_down(wlc_hw->d11core->bus);
-+                      bcma_host_pci_down(wlc_hw->d11core->bus);
-                       brcms_b_xtal(wlc_hw, OFF);
-               }
-       }
diff --git a/package/kernel/mac80211/patches/100-revert-cryptoapi-ports.patch b/package/kernel/mac80211/patches/100-revert-cryptoapi-ports.patch
new file mode 100644 (file)
index 0000000..ceca952
--- /dev/null
@@ -0,0 +1,2055 @@
+This patch reverts the following commits from wireless-testing:
+
+8ade538bf39b1ee53418528fdacd36b8e65621b9
+56c52da2d554f081e8fce58ecbcf6a40c605b95b
+2b2ba0db1c820d04d5143452d70012cd44d7b578
+00b9cfa3ff38401bd70c34b250ca13e5ea347b4a
+4f031fa9f188b2b0641ac20087d9e16bcfb4e49d
+6e1ee5d2e9e411892b5d84e3ea93e3fc88ac786c
+30ef7ef9672d92ab2cac37f60a31955c118321e7
+f359d3fe832e49eeec2232b2af5a9e3aee6b4862 (only the changes in aes_cmac.{c,h})
+7ec7c4a9a686c608315739ab6a2b0527a240883c
+---
+
+--- a/include/linux/ieee80211.h
++++ b/include/linux/ieee80211.h
+@@ -1017,15 +1017,6 @@ struct ieee80211_mmie {
+       u8 mic[8];
+ } __packed;
+-/* Management MIC information element (IEEE 802.11w) for GMAC and CMAC-256 */
+-struct ieee80211_mmie_16 {
+-      u8 element_id;
+-      u8 length;
+-      __le16 key_id;
+-      u8 sequence_number[6];
+-      u8 mic[16];
+-} __packed;
+-
+ struct ieee80211_vendor_ie {
+       u8 element_id;
+       u8 len;
+--- a/include/net/mac80211.h
++++ b/include/net/mac80211.h
+@@ -1306,8 +1306,8 @@ struct ieee80211_vif *wdev_to_ieee80211_
+  * @IEEE80211_KEY_FLAG_PAIRWISE: Set by mac80211, this flag indicates
+  *    that the key is pairwise rather then a shared key.
+  * @IEEE80211_KEY_FLAG_SW_MGMT_TX: This flag should be set by the driver for a
+- *    CCMP/GCMP key if it requires CCMP/GCMP encryption of management frames
+- *    (MFP) to be done in software.
++ *    CCMP key if it requires CCMP encryption of management frames (MFP) to
++ *    be done in software.
+  * @IEEE80211_KEY_FLAG_PUT_IV_SPACE: This flag should be set by the driver
+  *    if space should be prepared for the IV, but the IV
+  *    itself should not be generated. Do not set together with
+@@ -1322,7 +1322,7 @@ struct ieee80211_vif *wdev_to_ieee80211_
+  *    RX, if your crypto engine can't deal with TX you can also set the
+  *    %IEEE80211_KEY_FLAG_SW_MGMT_TX flag to encrypt such frames in SW.
+  * @IEEE80211_KEY_FLAG_GENERATE_IV_MGMT: This flag should be set by the
+- *    driver for a CCMP/GCMP key to indicate that is requires IV generation
++ *    driver for a CCMP key to indicate that is requires IV generation
+  *    only for managment frames (MFP).
+  * @IEEE80211_KEY_FLAG_RESERVE_TAILROOM: This flag should be set by the
+  *    driver for a key to indicate that sufficient tailroom must always
+@@ -4112,10 +4112,6 @@ void ieee80211_aes_cmac_calculate_k1_k2(
+  *    reverse order than in packet)
+  * @aes_cmac: PN data, most significant byte first (big endian,
+  *    reverse order than in packet)
+- * @aes_gmac: PN data, most significant byte first (big endian,
+- *    reverse order than in packet)
+- * @gcmp: PN data, most significant byte first (big endian,
+- *    reverse order than in packet)
+  */
+ struct ieee80211_key_seq {
+       union {
+@@ -4129,12 +4125,6 @@ struct ieee80211_key_seq {
+               struct {
+                       u8 pn[6];
+               } aes_cmac;
+-              struct {
+-                      u8 pn[6];
+-              } aes_gmac;
+-              struct {
+-                      u8 pn[6];
+-              } gcmp;
+       };
+ };
+@@ -4159,7 +4149,7 @@ void ieee80211_get_key_tx_seq(struct iee
+  * ieee80211_get_key_rx_seq - get key RX sequence counter
+  *
+  * @keyconf: the parameter passed with the set key
+- * @tid: The TID, or -1 for the management frame value (CCMP/GCMP only);
++ * @tid: The TID, or -1 for the management frame value (CCMP only);
+  *    the value on TID 0 is also used for non-QoS frames. For
+  *    CMAC, only TID 0 is valid.
+  * @seq: buffer to receive the sequence data
+@@ -4195,7 +4185,7 @@ void ieee80211_set_key_tx_seq(struct iee
+  * ieee80211_set_key_rx_seq - set key RX sequence counter
+  *
+  * @keyconf: the parameter passed with the set key
+- * @tid: The TID, or -1 for the management frame value (CCMP/GCMP only);
++ * @tid: The TID, or -1 for the management frame value (CCMP only);
+  *    the value on TID 0 is also used for non-QoS frames. For
+  *    CMAC, only TID 0 is valid.
+  * @seq: new sequence data
+--- a/net/mac80211/Kconfig
++++ b/net/mac80211/Kconfig
+@@ -5,8 +5,6 @@ config MAC80211
+       depends on CRYPTO
+       depends on CRYPTO_ARC4
+       depends on CRYPTO_AES
+-      select BPAUTO_CRYPTO_CCM
+-      depends on CRYPTO_GCM
+       depends on CRC32
+       select BPAUTO_AVERAGE
+       ---help---
+--- a/net/mac80211/Makefile
++++ b/net/mac80211/Makefile
+@@ -15,9 +15,7 @@ mac80211-y := \
+       michael.o \
+       tkip.o \
+       aes_ccm.o \
+-      aes_gcm.o \
+       aes_cmac.o \
+-      aes_gmac.o \
+       cfg.o \
+       ethtool.o \
+       rx.o \
+--- a/net/mac80211/aes_ccm.c
++++ b/net/mac80211/aes_ccm.c
+@@ -2,8 +2,6 @@
+  * Copyright 2003-2004, Instant802 Networks, Inc.
+  * Copyright 2005-2006, Devicescape Software, Inc.
+  *
+- * Rewrite: Copyright (C) 2013 Linaro Ltd <ard.biesheuvel@linaro.org>
+- *
+  * This program is free software; you can redistribute it and/or modify
+  * it under the terms of the GNU General Public License version 2 as
+  * published by the Free Software Foundation.
+@@ -19,82 +17,134 @@
+ #include "key.h"
+ #include "aes_ccm.h"
+-void ieee80211_aes_ccm_encrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad,
+-                             u8 *data, size_t data_len, u8 *mic,
+-                             size_t mic_len)
++static void aes_ccm_prepare(struct crypto_cipher *tfm, u8 *scratch, u8 *a)
++{
++      int i;
++      u8 *b_0, *aad, *b, *s_0;
++
++      b_0 = scratch + 3 * AES_BLOCK_SIZE;
++      aad = scratch + 4 * AES_BLOCK_SIZE;
++      b = scratch;
++      s_0 = scratch + AES_BLOCK_SIZE;
++
++      crypto_cipher_encrypt_one(tfm, b, b_0);
++
++      /* Extra Authenticate-only data (always two AES blocks) */
++      for (i = 0; i < AES_BLOCK_SIZE; i++)
++              aad[i] ^= b[i];
++      crypto_cipher_encrypt_one(tfm, b, aad);
++
++      aad += AES_BLOCK_SIZE;
++
++      for (i = 0; i < AES_BLOCK_SIZE; i++)
++              aad[i] ^= b[i];
++      crypto_cipher_encrypt_one(tfm, a, aad);
++
++      /* Mask out bits from auth-only-b_0 */
++      b_0[0] &= 0x07;
++
++      /* S_0 is used to encrypt T (= MIC) */
++      b_0[14] = 0;
++      b_0[15] = 0;
++      crypto_cipher_encrypt_one(tfm, s_0, b_0);
++}
++
++
++void ieee80211_aes_ccm_encrypt(struct crypto_cipher *tfm, u8 *scratch,
++                             u8 *data, size_t data_len,
++                             u8 *cdata, u8 *mic)
+ {
+-      struct scatterlist assoc, pt, ct[2];
++      int i, j, last_len, num_blocks;
++      u8 *pos, *cpos, *b, *s_0, *e, *b_0;
+-      char aead_req_data[sizeof(struct aead_request) +
+-                         crypto_aead_reqsize(tfm)]
+-              __aligned(__alignof__(struct aead_request));
+-      struct aead_request *aead_req = (void *) aead_req_data;
+-
+-      memset(aead_req, 0, sizeof(aead_req_data));
+-
+-      sg_init_one(&pt, data, data_len);
+-      sg_init_one(&assoc, &aad[2], be16_to_cpup((__be16 *)aad));
+-      sg_init_table(ct, 2);
+-      sg_set_buf(&ct[0], data, data_len);
+-      sg_set_buf(&ct[1], mic, mic_len);
+-
+-      aead_request_set_tfm(aead_req, tfm);
+-      aead_request_set_assoc(aead_req, &assoc, assoc.length);
+-      aead_request_set_crypt(aead_req, &pt, ct, data_len, b_0);
++      b = scratch;
++      s_0 = scratch + AES_BLOCK_SIZE;
++      e = scratch + 2 * AES_BLOCK_SIZE;
++      b_0 = scratch + 3 * AES_BLOCK_SIZE;
++
++      num_blocks = DIV_ROUND_UP(data_len, AES_BLOCK_SIZE);
++      last_len = data_len % AES_BLOCK_SIZE;
++      aes_ccm_prepare(tfm, scratch, b);
++
++      /* Process payload blocks */
++      pos = data;
++      cpos = cdata;
++      for (j = 1; j <= num_blocks; j++) {
++              int blen = (j == num_blocks && last_len) ?
++                      last_len : AES_BLOCK_SIZE;
++
++              /* Authentication followed by encryption */
++              for (i = 0; i < blen; i++)
++                      b[i] ^= pos[i];
++              crypto_cipher_encrypt_one(tfm, b, b);
++
++              b_0[14] = (j >> 8) & 0xff;
++              b_0[15] = j & 0xff;
++              crypto_cipher_encrypt_one(tfm, e, b_0);
++              for (i = 0; i < blen; i++)
++                      *cpos++ = *pos++ ^ e[i];
++      }
+-      crypto_aead_encrypt(aead_req);
++      for (i = 0; i < IEEE80211_CCMP_MIC_LEN; i++)
++              mic[i] = b[i] ^ s_0[i];
+ }
+-int ieee80211_aes_ccm_decrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad,
+-                            u8 *data, size_t data_len, u8 *mic,
+-                            size_t mic_len)
++
++int ieee80211_aes_ccm_decrypt(struct crypto_cipher *tfm, u8 *scratch,
++                            u8 *cdata, size_t data_len, u8 *mic, u8 *data)
+ {
+-      struct scatterlist assoc, pt, ct[2];
+-      char aead_req_data[sizeof(struct aead_request) +
+-                         crypto_aead_reqsize(tfm)]
+-              __aligned(__alignof__(struct aead_request));
+-      struct aead_request *aead_req = (void *) aead_req_data;
+-
+-      if (data_len == 0)
+-              return -EINVAL;
+-
+-      memset(aead_req, 0, sizeof(aead_req_data));
+-
+-      sg_init_one(&pt, data, data_len);
+-      sg_init_one(&assoc, &aad[2], be16_to_cpup((__be16 *)aad));
+-      sg_init_table(ct, 2);
+-      sg_set_buf(&ct[0], data, data_len);
+-      sg_set_buf(&ct[1], mic, mic_len);
+-
+-      aead_request_set_tfm(aead_req, tfm);
+-      aead_request_set_assoc(aead_req, &assoc, assoc.length);
+-      aead_request_set_crypt(aead_req, ct, &pt, data_len + mic_len, b_0);
++      int i, j, last_len, num_blocks;
++      u8 *pos, *cpos, *b, *s_0, *a, *b_0;
++
++      b = scratch;
++      s_0 = scratch + AES_BLOCK_SIZE;
++      a = scratch + 2 * AES_BLOCK_SIZE;
++      b_0 = scratch + 3 * AES_BLOCK_SIZE;
++
++      num_blocks = DIV_ROUND_UP(data_len, AES_BLOCK_SIZE);
++      last_len = data_len % AES_BLOCK_SIZE;
++      aes_ccm_prepare(tfm, scratch, a);
++
++      /* Process payload blocks */
++      cpos = cdata;
++      pos = data;
++      for (j = 1; j <= num_blocks; j++) {
++              int blen = (j == num_blocks && last_len) ?
++                      last_len : AES_BLOCK_SIZE;
++
++              /* Decryption followed by authentication */
++              b_0[14] = (j >> 8) & 0xff;
++              b_0[15] = j & 0xff;
++              crypto_cipher_encrypt_one(tfm, b, b_0);
++              for (i = 0; i < blen; i++) {
++                      *pos = *cpos++ ^ b[i];
++                      a[i] ^= *pos++;
++              }
++              crypto_cipher_encrypt_one(tfm, a, a);
++      }
++
++      for (i = 0; i < IEEE80211_CCMP_MIC_LEN; i++) {
++              if ((mic[i] ^ s_0[i]) != a[i])
++                      return -1;
++      }
+-      return crypto_aead_decrypt(aead_req);
++      return 0;
+ }
+-struct crypto_aead *ieee80211_aes_key_setup_encrypt(const u8 key[],
+-                                                  size_t key_len,
+-                                                  size_t mic_len)
++
++struct crypto_cipher *ieee80211_aes_key_setup_encrypt(const u8 key[])
+ {
+-      struct crypto_aead *tfm;
+-      int err;
++      struct crypto_cipher *tfm;
+-      tfm = crypto_alloc_aead("ccm(aes)", 0, CRYPTO_ALG_ASYNC);
+-      if (IS_ERR(tfm))
+-              return tfm;
+-
+-      err = crypto_aead_setkey(tfm, key, key_len);
+-      if (!err)
+-              err = crypto_aead_setauthsize(tfm, mic_len);
+-      if (!err)
+-              return tfm;
++      tfm = crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC);
++      if (!IS_ERR(tfm))
++              crypto_cipher_setkey(tfm, key, WLAN_KEY_LEN_CCMP);
+-      crypto_free_aead(tfm);
+-      return ERR_PTR(err);
++      return tfm;
+ }
+-void ieee80211_aes_key_free(struct crypto_aead *tfm)
++
++void ieee80211_aes_key_free(struct crypto_cipher *tfm)
+ {
+-      crypto_free_aead(tfm);
++      crypto_free_cipher(tfm);
+ }
+--- a/net/mac80211/aes_ccm.h
++++ b/net/mac80211/aes_ccm.h
+@@ -12,15 +12,13 @@
+ #include <linux/crypto.h>
+-struct crypto_aead *ieee80211_aes_key_setup_encrypt(const u8 key[],
+-                                                  size_t key_len,
+-                                                  size_t mic_len);
+-void ieee80211_aes_ccm_encrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad,
+-                             u8 *data, size_t data_len, u8 *mic,
+-                             size_t mic_len);
+-int ieee80211_aes_ccm_decrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad,
+-                            u8 *data, size_t data_len, u8 *mic,
+-                            size_t mic_len);
+-void ieee80211_aes_key_free(struct crypto_aead *tfm);
++struct crypto_cipher *ieee80211_aes_key_setup_encrypt(const u8 key[]);
++void ieee80211_aes_ccm_encrypt(struct crypto_cipher *tfm, u8 *scratch,
++                             u8 *data, size_t data_len,
++                             u8 *cdata, u8 *mic);
++int ieee80211_aes_ccm_decrypt(struct crypto_cipher *tfm, u8 *scratch,
++                            u8 *cdata, size_t data_len,
++                            u8 *mic, u8 *data);
++void ieee80211_aes_key_free(struct crypto_cipher *tfm);
+ #endif /* AES_CCM_H */
+--- a/net/mac80211/aes_cmac.c
++++ b/net/mac80211/aes_cmac.c
+@@ -18,8 +18,8 @@
+ #include "key.h"
+ #include "aes_cmac.h"
++#define AES_CMAC_KEY_LEN 16
+ #define CMAC_TLEN 8 /* CMAC TLen = 64 bits (8 octets) */
+-#define CMAC_TLEN_256 16 /* CMAC TLen = 128 bits (16 octets) */
+ #define AAD_LEN 20
+@@ -35,9 +35,9 @@ static void gf_mulx(u8 *pad)
+               pad[AES_BLOCK_SIZE - 1] ^= 0x87;
+ }
+-static void aes_cmac_vector(struct crypto_cipher *tfm, size_t num_elem,
+-                          const u8 *addr[], const size_t *len, u8 *mac,
+-                          size_t mac_len)
++
++static void aes_128_cmac_vector(struct crypto_cipher *tfm, size_t num_elem,
++                              const u8 *addr[], const size_t *len, u8 *mac)
+ {
+       u8 cbc[AES_BLOCK_SIZE], pad[AES_BLOCK_SIZE];
+       const u8 *pos, *end;
+@@ -88,7 +88,7 @@ static void aes_cmac_vector(struct crypt
+       for (i = 0; i < AES_BLOCK_SIZE; i++)
+               pad[i] ^= cbc[i];
+       crypto_cipher_encrypt_one(tfm, pad, pad);
+-      memcpy(mac, pad, mac_len);
++      memcpy(mac, pad, CMAC_TLEN);
+ }
+@@ -107,35 +107,17 @@ void ieee80211_aes_cmac(struct crypto_ci
+       addr[2] = zero;
+       len[2] = CMAC_TLEN;
+-      aes_cmac_vector(tfm, 3, addr, len, mic, CMAC_TLEN);
++      aes_128_cmac_vector(tfm, 3, addr, len, mic);
+ }
+-void ieee80211_aes_cmac_256(struct crypto_cipher *tfm, const u8 *aad,
+-                          const u8 *data, size_t data_len, u8 *mic)
+-{
+-      const u8 *addr[3];
+-      size_t len[3];
+-      u8 zero[CMAC_TLEN_256];
+-
+-      memset(zero, 0, CMAC_TLEN_256);
+-      addr[0] = aad;
+-      len[0] = AAD_LEN;
+-      addr[1] = data;
+-      len[1] = data_len - CMAC_TLEN_256;
+-      addr[2] = zero;
+-      len[2] = CMAC_TLEN_256;
+-
+-      aes_cmac_vector(tfm, 3, addr, len, mic, CMAC_TLEN_256);
+-}
+-struct crypto_cipher *ieee80211_aes_cmac_key_setup(const u8 key[],
+-                                                 size_t key_len)
++struct crypto_cipher * ieee80211_aes_cmac_key_setup(const u8 key[])
+ {
+       struct crypto_cipher *tfm;
+       tfm = crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC);
+       if (!IS_ERR(tfm))
+-              crypto_cipher_setkey(tfm, key, key_len);
++              crypto_cipher_setkey(tfm, key, AES_CMAC_KEY_LEN);
+       return tfm;
+ }
+--- a/net/mac80211/aes_cmac.h
++++ b/net/mac80211/aes_cmac.h
+@@ -11,12 +11,9 @@
+ #include <linux/crypto.h>
+-struct crypto_cipher *ieee80211_aes_cmac_key_setup(const u8 key[],
+-                                                 size_t key_len);
++struct crypto_cipher * ieee80211_aes_cmac_key_setup(const u8 key[]);
+ void ieee80211_aes_cmac(struct crypto_cipher *tfm, const u8 *aad,
+                       const u8 *data, size_t data_len, u8 *mic);
+-void ieee80211_aes_cmac_256(struct crypto_cipher *tfm, const u8 *aad,
+-                          const u8 *data, size_t data_len, u8 *mic);
+ void ieee80211_aes_cmac_key_free(struct crypto_cipher *tfm);
+ #endif /* AES_CMAC_H */
+--- a/net/mac80211/aes_gcm.c
++++ /dev/null
+@@ -1,95 +0,0 @@
+-/*
+- * Copyright 2014-2015, Qualcomm Atheros, Inc.
+- *
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the GNU General Public License version 2 as
+- * published by the Free Software Foundation.
+- */
+-
+-#include <linux/kernel.h>
+-#include <linux/types.h>
+-#include <linux/crypto.h>
+-#include <linux/err.h>
+-#include <crypto/aes.h>
+-
+-#include <net/mac80211.h>
+-#include "key.h"
+-#include "aes_gcm.h"
+-
+-void ieee80211_aes_gcm_encrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad,
+-                             u8 *data, size_t data_len, u8 *mic)
+-{
+-      struct scatterlist assoc, pt, ct[2];
+-
+-      char aead_req_data[sizeof(struct aead_request) +
+-                         crypto_aead_reqsize(tfm)]
+-              __aligned(__alignof__(struct aead_request));
+-      struct aead_request *aead_req = (void *)aead_req_data;
+-
+-      memset(aead_req, 0, sizeof(aead_req_data));
+-
+-      sg_init_one(&pt, data, data_len);
+-      sg_init_one(&assoc, &aad[2], be16_to_cpup((__be16 *)aad));
+-      sg_init_table(ct, 2);
+-      sg_set_buf(&ct[0], data, data_len);
+-      sg_set_buf(&ct[1], mic, IEEE80211_GCMP_MIC_LEN);
+-
+-      aead_request_set_tfm(aead_req, tfm);
+-      aead_request_set_assoc(aead_req, &assoc, assoc.length);
+-      aead_request_set_crypt(aead_req, &pt, ct, data_len, j_0);
+-
+-      crypto_aead_encrypt(aead_req);
+-}
+-
+-int ieee80211_aes_gcm_decrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad,
+-                            u8 *data, size_t data_len, u8 *mic)
+-{
+-      struct scatterlist assoc, pt, ct[2];
+-      char aead_req_data[sizeof(struct aead_request) +
+-                         crypto_aead_reqsize(tfm)]
+-              __aligned(__alignof__(struct aead_request));
+-      struct aead_request *aead_req = (void *)aead_req_data;
+-
+-      if (data_len == 0)
+-              return -EINVAL;
+-
+-      memset(aead_req, 0, sizeof(aead_req_data));
+-
+-      sg_init_one(&pt, data, data_len);
+-      sg_init_one(&assoc, &aad[2], be16_to_cpup((__be16 *)aad));
+-      sg_init_table(ct, 2);
+-      sg_set_buf(&ct[0], data, data_len);
+-      sg_set_buf(&ct[1], mic, IEEE80211_GCMP_MIC_LEN);
+-
+-      aead_request_set_tfm(aead_req, tfm);
+-      aead_request_set_assoc(aead_req, &assoc, assoc.length);
+-      aead_request_set_crypt(aead_req, ct, &pt,
+-                             data_len + IEEE80211_GCMP_MIC_LEN, j_0);
+-
+-      return crypto_aead_decrypt(aead_req);
+-}
+-
+-struct crypto_aead *ieee80211_aes_gcm_key_setup_encrypt(const u8 key[],
+-                                                      size_t key_len)
+-{
+-      struct crypto_aead *tfm;
+-      int err;
+-
+-      tfm = crypto_alloc_aead("gcm(aes)", 0, CRYPTO_ALG_ASYNC);
+-      if (IS_ERR(tfm))
+-              return tfm;
+-
+-      err = crypto_aead_setkey(tfm, key, key_len);
+-      if (!err)
+-              err = crypto_aead_setauthsize(tfm, IEEE80211_GCMP_MIC_LEN);
+-      if (!err)
+-              return tfm;
+-
+-      crypto_free_aead(tfm);
+-      return ERR_PTR(err);
+-}
+-
+-void ieee80211_aes_gcm_key_free(struct crypto_aead *tfm)
+-{
+-      crypto_free_aead(tfm);
+-}
+--- a/net/mac80211/aes_gcm.h
++++ /dev/null
+@@ -1,22 +0,0 @@
+-/*
+- * Copyright 2014-2015, Qualcomm Atheros, Inc.
+- *
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the GNU General Public License version 2 as
+- * published by the Free Software Foundation.
+- */
+-
+-#ifndef AES_GCM_H
+-#define AES_GCM_H
+-
+-#include <linux/crypto.h>
+-
+-void ieee80211_aes_gcm_encrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad,
+-                             u8 *data, size_t data_len, u8 *mic);
+-int ieee80211_aes_gcm_decrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad,
+-                            u8 *data, size_t data_len, u8 *mic);
+-struct crypto_aead *ieee80211_aes_gcm_key_setup_encrypt(const u8 key[],
+-                                                      size_t key_len);
+-void ieee80211_aes_gcm_key_free(struct crypto_aead *tfm);
+-
+-#endif /* AES_GCM_H */
+--- a/net/mac80211/aes_gmac.c
++++ /dev/null
+@@ -1,84 +0,0 @@
+-/*
+- * AES-GMAC for IEEE 802.11 BIP-GMAC-128 and BIP-GMAC-256
+- * Copyright 2015, Qualcomm Atheros, Inc.
+- *
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the GNU General Public License version 2 as
+- * published by the Free Software Foundation.
+- */
+-
+-#include <linux/kernel.h>
+-#include <linux/types.h>
+-#include <linux/crypto.h>
+-#include <linux/err.h>
+-#include <crypto/aes.h>
+-
+-#include <net/mac80211.h>
+-#include "key.h"
+-#include "aes_gmac.h"
+-
+-#define GMAC_MIC_LEN 16
+-#define GMAC_NONCE_LEN 12
+-#define AAD_LEN 20
+-
+-int ieee80211_aes_gmac(struct crypto_aead *tfm, const u8 *aad, u8 *nonce,
+-                     const u8 *data, size_t data_len, u8 *mic)
+-{
+-      struct scatterlist sg[3], ct[1];
+-      char aead_req_data[sizeof(struct aead_request) +
+-                         crypto_aead_reqsize(tfm)]
+-              __aligned(__alignof__(struct aead_request));
+-      struct aead_request *aead_req = (void *)aead_req_data;
+-      u8 zero[GMAC_MIC_LEN], iv[AES_BLOCK_SIZE];
+-
+-      if (data_len < GMAC_MIC_LEN)
+-              return -EINVAL;
+-
+-      memset(aead_req, 0, sizeof(aead_req_data));
+-
+-      memset(zero, 0, GMAC_MIC_LEN);
+-      sg_init_table(sg, 3);
+-      sg_set_buf(&sg[0], aad, AAD_LEN);
+-      sg_set_buf(&sg[1], data, data_len - GMAC_MIC_LEN);
+-      sg_set_buf(&sg[2], zero, GMAC_MIC_LEN);
+-
+-      memcpy(iv, nonce, GMAC_NONCE_LEN);
+-      memset(iv + GMAC_NONCE_LEN, 0, sizeof(iv) - GMAC_NONCE_LEN);
+-      iv[AES_BLOCK_SIZE - 1] = 0x01;
+-
+-      sg_init_table(ct, 1);
+-      sg_set_buf(&ct[0], mic, GMAC_MIC_LEN);
+-
+-      aead_request_set_tfm(aead_req, tfm);
+-      aead_request_set_assoc(aead_req, sg, AAD_LEN + data_len);
+-      aead_request_set_crypt(aead_req, NULL, ct, 0, iv);
+-
+-      crypto_aead_encrypt(aead_req);
+-
+-      return 0;
+-}
+-
+-struct crypto_aead *ieee80211_aes_gmac_key_setup(const u8 key[],
+-                                               size_t key_len)
+-{
+-      struct crypto_aead *tfm;
+-      int err;
+-
+-      tfm = crypto_alloc_aead("gcm(aes)", 0, CRYPTO_ALG_ASYNC);
+-      if (IS_ERR(tfm))
+-              return tfm;
+-
+-      err = crypto_aead_setkey(tfm, key, key_len);
+-      if (!err)
+-              return tfm;
+-      if (!err)
+-              err = crypto_aead_setauthsize(tfm, GMAC_MIC_LEN);
+-
+-      crypto_free_aead(tfm);
+-      return ERR_PTR(err);
+-}
+-
+-void ieee80211_aes_gmac_key_free(struct crypto_aead *tfm)
+-{
+-      crypto_free_aead(tfm);
+-}
+--- a/net/mac80211/aes_gmac.h
++++ /dev/null
+@@ -1,20 +0,0 @@
+-/*
+- * Copyright 2015, Qualcomm Atheros, Inc.
+- *
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the GNU General Public License version 2 as
+- * published by the Free Software Foundation.
+- */
+-
+-#ifndef AES_GMAC_H
+-#define AES_GMAC_H
+-
+-#include <linux/crypto.h>
+-
+-struct crypto_aead *ieee80211_aes_gmac_key_setup(const u8 key[],
+-                                               size_t key_len);
+-int ieee80211_aes_gmac(struct crypto_aead *tfm, const u8 *aad, u8 *nonce,
+-                     const u8 *data, size_t data_len, u8 *mic);
+-void ieee80211_aes_gmac_key_free(struct crypto_aead *tfm);
+-
+-#endif /* AES_GMAC_H */
+--- a/net/mac80211/cfg.c
++++ b/net/mac80211/cfg.c
+@@ -162,13 +162,8 @@ static int ieee80211_add_key(struct wiph
+                       return -EINVAL;
+               break;
+       case WLAN_CIPHER_SUITE_CCMP:
+-      case WLAN_CIPHER_SUITE_CCMP_256:
+       case WLAN_CIPHER_SUITE_AES_CMAC:
+-      case WLAN_CIPHER_SUITE_BIP_CMAC_256:
+-      case WLAN_CIPHER_SUITE_BIP_GMAC_128:
+-      case WLAN_CIPHER_SUITE_BIP_GMAC_256:
+       case WLAN_CIPHER_SUITE_GCMP:
+-      case WLAN_CIPHER_SUITE_GCMP_256:
+               break;
+       default:
+               cs = ieee80211_cs_get(local, params->cipher, sdata->vif.type);
+@@ -353,7 +348,6 @@ static int ieee80211_get_key(struct wiph
+               params.seq_len = 6;
+               break;
+       case WLAN_CIPHER_SUITE_CCMP:
+-      case WLAN_CIPHER_SUITE_CCMP_256:
+               pn64 = atomic64_read(&key->u.ccmp.tx_pn);
+               seq[0] = pn64;
+               seq[1] = pn64 >> 8;
+@@ -365,35 +359,10 @@ static int ieee80211_get_key(struct wiph
+               params.seq_len = 6;
+               break;
+       case WLAN_CIPHER_SUITE_AES_CMAC:
+-      case WLAN_CIPHER_SUITE_BIP_CMAC_256:
+               pn64 = atomic64_read(&key->u.aes_cmac.tx_pn);
+               seq[0] = pn64;
+               seq[1] = pn64 >> 8;
+               seq[2] = pn64 >> 16;
+-              seq[3] = pn64 >> 24;
+-              seq[4] = pn64 >> 32;
+-              seq[5] = pn64 >> 40;
+-              params.seq = seq;
+-              params.seq_len = 6;
+-              break;
+-      case WLAN_CIPHER_SUITE_BIP_GMAC_128:
+-      case WLAN_CIPHER_SUITE_BIP_GMAC_256:
+-              pn64 = atomic64_read(&key->u.aes_gmac.tx_pn);
+-              seq[0] = pn64;
+-              seq[1] = pn64 >> 8;
+-              seq[2] = pn64 >> 16;
+-              seq[3] = pn64 >> 24;
+-              seq[4] = pn64 >> 32;
+-              seq[5] = pn64 >> 40;
+-              params.seq = seq;
+-              params.seq_len = 6;
+-              break;
+-      case WLAN_CIPHER_SUITE_GCMP:
+-      case WLAN_CIPHER_SUITE_GCMP_256:
+-              pn64 = atomic64_read(&key->u.gcmp.tx_pn);
+-              seq[0] = pn64;
+-              seq[1] = pn64 >> 8;
+-              seq[2] = pn64 >> 16;
+               seq[3] = pn64 >> 24;
+               seq[4] = pn64 >> 32;
+               seq[5] = pn64 >> 40;
+--- a/net/mac80211/debugfs_key.c
++++ b/net/mac80211/debugfs_key.c
+@@ -94,33 +94,17 @@ static ssize_t key_tx_spec_read(struct f
+                               key->u.tkip.tx.iv16);
+               break;
+       case WLAN_CIPHER_SUITE_CCMP:
+-      case WLAN_CIPHER_SUITE_CCMP_256:
+               pn = atomic64_read(&key->u.ccmp.tx_pn);
+               len = scnprintf(buf, sizeof(buf), "%02x%02x%02x%02x%02x%02x\n",
+                               (u8)(pn >> 40), (u8)(pn >> 32), (u8)(pn >> 24),
+                               (u8)(pn >> 16), (u8)(pn >> 8), (u8)pn);
+               break;
+       case WLAN_CIPHER_SUITE_AES_CMAC:
+-      case WLAN_CIPHER_SUITE_BIP_CMAC_256:
+               pn = atomic64_read(&key->u.aes_cmac.tx_pn);
+               len = scnprintf(buf, sizeof(buf), "%02x%02x%02x%02x%02x%02x\n",
+                               (u8)(pn >> 40), (u8)(pn >> 32), (u8)(pn >> 24),
+                               (u8)(pn >> 16), (u8)(pn >> 8), (u8)pn);
+               break;
+-      case WLAN_CIPHER_SUITE_BIP_GMAC_128:
+-      case WLAN_CIPHER_SUITE_BIP_GMAC_256:
+-              pn = atomic64_read(&key->u.aes_gmac.tx_pn);
+-              len = scnprintf(buf, sizeof(buf), "%02x%02x%02x%02x%02x%02x\n",
+-                              (u8)(pn >> 40), (u8)(pn >> 32), (u8)(pn >> 24),
+-                              (u8)(pn >> 16), (u8)(pn >> 8), (u8)pn);
+-              break;
+-      case WLAN_CIPHER_SUITE_GCMP:
+-      case WLAN_CIPHER_SUITE_GCMP_256:
+-              pn = atomic64_read(&key->u.gcmp.tx_pn);
+-              len = scnprintf(buf, sizeof(buf), "%02x%02x%02x%02x%02x%02x\n",
+-                              (u8)(pn >> 40), (u8)(pn >> 32), (u8)(pn >> 24),
+-                              (u8)(pn >> 16), (u8)(pn >> 8), (u8)pn);
+-              break;
+       default:
+               return 0;
+       }
+@@ -150,7 +134,6 @@ static ssize_t key_rx_spec_read(struct f
+               len = p - buf;
+               break;
+       case WLAN_CIPHER_SUITE_CCMP:
+-      case WLAN_CIPHER_SUITE_CCMP_256:
+               for (i = 0; i < IEEE80211_NUM_TIDS + 1; i++) {
+                       rpn = key->u.ccmp.rx_pn[i];
+                       p += scnprintf(p, sizeof(buf)+buf-p,
+@@ -161,7 +144,6 @@ static ssize_t key_rx_spec_read(struct f
+               len = p - buf;
+               break;
+       case WLAN_CIPHER_SUITE_AES_CMAC:
+-      case WLAN_CIPHER_SUITE_BIP_CMAC_256:
+               rpn = key->u.aes_cmac.rx_pn;
+               p += scnprintf(p, sizeof(buf)+buf-p,
+                              "%02x%02x%02x%02x%02x%02x\n",
+@@ -169,26 +151,6 @@ static ssize_t key_rx_spec_read(struct f
+                              rpn[3], rpn[4], rpn[5]);
+               len = p - buf;
+               break;
+-      case WLAN_CIPHER_SUITE_BIP_GMAC_128:
+-      case WLAN_CIPHER_SUITE_BIP_GMAC_256:
+-              rpn = key->u.aes_gmac.rx_pn;
+-              p += scnprintf(p, sizeof(buf)+buf-p,
+-                             "%02x%02x%02x%02x%02x%02x\n",
+-                             rpn[0], rpn[1], rpn[2],
+-                             rpn[3], rpn[4], rpn[5]);
+-              len = p - buf;
+-              break;
+-      case WLAN_CIPHER_SUITE_GCMP:
+-      case WLAN_CIPHER_SUITE_GCMP_256:
+-              for (i = 0; i < IEEE80211_NUM_TIDS + 1; i++) {
+-                      rpn = key->u.gcmp.rx_pn[i];
+-                      p += scnprintf(p, sizeof(buf)+buf-p,
+-                                     "%02x%02x%02x%02x%02x%02x\n",
+-                                     rpn[0], rpn[1], rpn[2],
+-                                     rpn[3], rpn[4], rpn[5]);
+-              }
+-              len = p - buf;
+-              break;
+       default:
+               return 0;
+       }
+@@ -205,23 +167,12 @@ static ssize_t key_replays_read(struct f
+       switch (key->conf.cipher) {
+       case WLAN_CIPHER_SUITE_CCMP:
+-      case WLAN_CIPHER_SUITE_CCMP_256:
+               len = scnprintf(buf, sizeof(buf), "%u\n", key->u.ccmp.replays);
+               break;
+       case WLAN_CIPHER_SUITE_AES_CMAC:
+-      case WLAN_CIPHER_SUITE_BIP_CMAC_256:
+               len = scnprintf(buf, sizeof(buf), "%u\n",
+                               key->u.aes_cmac.replays);
+               break;
+-      case WLAN_CIPHER_SUITE_BIP_GMAC_128:
+-      case WLAN_CIPHER_SUITE_BIP_GMAC_256:
+-              len = scnprintf(buf, sizeof(buf), "%u\n",
+-                              key->u.aes_gmac.replays);
+-              break;
+-      case WLAN_CIPHER_SUITE_GCMP:
+-      case WLAN_CIPHER_SUITE_GCMP_256:
+-              len = scnprintf(buf, sizeof(buf), "%u\n", key->u.gcmp.replays);
+-              break;
+       default:
+               return 0;
+       }
+@@ -238,15 +189,9 @@ static ssize_t key_icverrors_read(struct
+       switch (key->conf.cipher) {
+       case WLAN_CIPHER_SUITE_AES_CMAC:
+-      case WLAN_CIPHER_SUITE_BIP_CMAC_256:
+               len = scnprintf(buf, sizeof(buf), "%u\n",
+                               key->u.aes_cmac.icverrors);
+               break;
+-      case WLAN_CIPHER_SUITE_BIP_GMAC_128:
+-      case WLAN_CIPHER_SUITE_BIP_GMAC_256:
+-              len = scnprintf(buf, sizeof(buf), "%u\n",
+-                              key->u.aes_gmac.icverrors);
+-              break;
+       default:
+               return 0;
+       }
+--- a/net/mac80211/key.c
++++ b/net/mac80211/key.c
+@@ -24,8 +24,6 @@
+ #include "debugfs_key.h"
+ #include "aes_ccm.h"
+ #include "aes_cmac.h"
+-#include "aes_gmac.h"
+-#include "aes_gcm.h"
+ /**
+@@ -164,13 +162,7 @@ static int ieee80211_key_enable_hw_accel
+       case WLAN_CIPHER_SUITE_WEP104:
+       case WLAN_CIPHER_SUITE_TKIP:
+       case WLAN_CIPHER_SUITE_CCMP:
+-      case WLAN_CIPHER_SUITE_CCMP_256:
+       case WLAN_CIPHER_SUITE_AES_CMAC:
+-      case WLAN_CIPHER_SUITE_BIP_CMAC_256:
+-      case WLAN_CIPHER_SUITE_BIP_GMAC_128:
+-      case WLAN_CIPHER_SUITE_BIP_GMAC_256:
+-      case WLAN_CIPHER_SUITE_GCMP:
+-      case WLAN_CIPHER_SUITE_GCMP_256:
+               /* all of these we can do in software - if driver can */
+               if (ret == 1)
+                       return 0;
+@@ -394,26 +386,7 @@ ieee80211_key_alloc(u32 cipher, int idx,
+                * Initialize AES key state here as an optimization so that
+                * it does not need to be initialized for every packet.
+                */
+-              key->u.ccmp.tfm = ieee80211_aes_key_setup_encrypt(
+-                      key_data, key_len, IEEE80211_CCMP_MIC_LEN);
+-              if (IS_ERR(key->u.ccmp.tfm)) {
+-                      err = PTR_ERR(key->u.ccmp.tfm);
+-                      kfree(key);
+-                      return ERR_PTR(err);
+-              }
+-              break;
+-      case WLAN_CIPHER_SUITE_CCMP_256:
+-              key->conf.iv_len = IEEE80211_CCMP_256_HDR_LEN;
+-              key->conf.icv_len = IEEE80211_CCMP_256_MIC_LEN;
+-              for (i = 0; seq && i < IEEE80211_NUM_TIDS + 1; i++)
+-                      for (j = 0; j < IEEE80211_CCMP_256_PN_LEN; j++)
+-                              key->u.ccmp.rx_pn[i][j] =
+-                                      seq[IEEE80211_CCMP_256_PN_LEN - j - 1];
+-              /* Initialize AES key state here as an optimization so that
+-               * it does not need to be initialized for every packet.
+-               */
+-              key->u.ccmp.tfm = ieee80211_aes_key_setup_encrypt(
+-                      key_data, key_len, IEEE80211_CCMP_256_MIC_LEN);
++              key->u.ccmp.tfm = ieee80211_aes_key_setup_encrypt(key_data);
+               if (IS_ERR(key->u.ccmp.tfm)) {
+                       err = PTR_ERR(key->u.ccmp.tfm);
+                       kfree(key);
+@@ -421,12 +394,8 @@ ieee80211_key_alloc(u32 cipher, int idx,
+               }
+               break;
+       case WLAN_CIPHER_SUITE_AES_CMAC:
+-      case WLAN_CIPHER_SUITE_BIP_CMAC_256:
+               key->conf.iv_len = 0;
+-              if (cipher == WLAN_CIPHER_SUITE_AES_CMAC)
+-                      key->conf.icv_len = sizeof(struct ieee80211_mmie);
+-              else
+-                      key->conf.icv_len = sizeof(struct ieee80211_mmie_16);
++              key->conf.icv_len = sizeof(struct ieee80211_mmie);
+               if (seq)
+                       for (j = 0; j < IEEE80211_CMAC_PN_LEN; j++)
+                               key->u.aes_cmac.rx_pn[j] =
+@@ -436,51 +405,13 @@ ieee80211_key_alloc(u32 cipher, int idx,
+                * it does not need to be initialized for every packet.
+                */
+               key->u.aes_cmac.tfm =
+-                      ieee80211_aes_cmac_key_setup(key_data, key_len);
++                      ieee80211_aes_cmac_key_setup(key_data);
+               if (IS_ERR(key->u.aes_cmac.tfm)) {
+                       err = PTR_ERR(key->u.aes_cmac.tfm);
+                       kfree(key);
+                       return ERR_PTR(err);
+               }
+               break;
+-      case WLAN_CIPHER_SUITE_BIP_GMAC_128:
+-      case WLAN_CIPHER_SUITE_BIP_GMAC_256:
+-              key->conf.iv_len = 0;
+-              key->conf.icv_len = sizeof(struct ieee80211_mmie_16);
+-              if (seq)
+-                      for (j = 0; j < IEEE80211_GMAC_PN_LEN; j++)
+-                              key->u.aes_gmac.rx_pn[j] =
+-                                      seq[IEEE80211_GMAC_PN_LEN - j - 1];
+-              /* Initialize AES key state here as an optimization so that
+-               * it does not need to be initialized for every packet.
+-               */
+-              key->u.aes_gmac.tfm =
+-                      ieee80211_aes_gmac_key_setup(key_data, key_len);
+-              if (IS_ERR(key->u.aes_gmac.tfm)) {
+-                      err = PTR_ERR(key->u.aes_gmac.tfm);
+-                      kfree(key);
+-                      return ERR_PTR(err);
+-              }
+-              break;
+-      case WLAN_CIPHER_SUITE_GCMP:
+-      case WLAN_CIPHER_SUITE_GCMP_256:
+-              key->conf.iv_len = IEEE80211_GCMP_HDR_LEN;
+-              key->conf.icv_len = IEEE80211_GCMP_MIC_LEN;
+-              for (i = 0; seq && i < IEEE80211_NUM_TIDS + 1; i++)
+-                      for (j = 0; j < IEEE80211_GCMP_PN_LEN; j++)
+-                              key->u.gcmp.rx_pn[i][j] =
+-                                      seq[IEEE80211_GCMP_PN_LEN - j - 1];
+-              /* Initialize AES key state here as an optimization so that
+-               * it does not need to be initialized for every packet.
+-               */
+-              key->u.gcmp.tfm = ieee80211_aes_gcm_key_setup_encrypt(key_data,
+-                                                                    key_len);
+-              if (IS_ERR(key->u.gcmp.tfm)) {
+-                      err = PTR_ERR(key->u.gcmp.tfm);
+-                      kfree(key);
+-                      return ERR_PTR(err);
+-              }
+-              break;
+       default:
+               if (cs) {
+                       size_t len = (seq_len > MAX_PN_LEN) ?
+@@ -502,24 +433,10 @@ ieee80211_key_alloc(u32 cipher, int idx,
+ static void ieee80211_key_free_common(struct ieee80211_key *key)
+ {
+-      switch (key->conf.cipher) {
+-      case WLAN_CIPHER_SUITE_CCMP:
+-      case WLAN_CIPHER_SUITE_CCMP_256:
++      if (key->conf.cipher == WLAN_CIPHER_SUITE_CCMP)
+               ieee80211_aes_key_free(key->u.ccmp.tfm);
+-              break;
+-      case WLAN_CIPHER_SUITE_AES_CMAC:
+-      case WLAN_CIPHER_SUITE_BIP_CMAC_256:
++      if (key->conf.cipher == WLAN_CIPHER_SUITE_AES_CMAC)
+               ieee80211_aes_cmac_key_free(key->u.aes_cmac.tfm);
+-              break;
+-      case WLAN_CIPHER_SUITE_BIP_GMAC_128:
+-      case WLAN_CIPHER_SUITE_BIP_GMAC_256:
+-              ieee80211_aes_gmac_key_free(key->u.aes_gmac.tfm);
+-              break;
+-      case WLAN_CIPHER_SUITE_GCMP:
+-      case WLAN_CIPHER_SUITE_GCMP_256:
+-              ieee80211_aes_gcm_key_free(key->u.gcmp.tfm);
+-              break;
+-      }
+       kzfree(key);
+ }
+@@ -826,7 +743,6 @@ void ieee80211_get_key_tx_seq(struct iee
+               seq->tkip.iv16 = key->u.tkip.tx.iv16;
+               break;
+       case WLAN_CIPHER_SUITE_CCMP:
+-      case WLAN_CIPHER_SUITE_CCMP_256:
+               pn64 = atomic64_read(&key->u.ccmp.tx_pn);
+               seq->ccmp.pn[5] = pn64;
+               seq->ccmp.pn[4] = pn64 >> 8;
+@@ -836,7 +752,6 @@ void ieee80211_get_key_tx_seq(struct iee
+               seq->ccmp.pn[0] = pn64 >> 40;
+               break;
+       case WLAN_CIPHER_SUITE_AES_CMAC:
+-      case WLAN_CIPHER_SUITE_BIP_CMAC_256:
+               pn64 = atomic64_read(&key->u.aes_cmac.tx_pn);
+               seq->ccmp.pn[5] = pn64;
+               seq->ccmp.pn[4] = pn64 >> 8;
+@@ -845,26 +760,6 @@ void ieee80211_get_key_tx_seq(struct iee
+               seq->ccmp.pn[1] = pn64 >> 32;
+               seq->ccmp.pn[0] = pn64 >> 40;
+               break;
+-      case WLAN_CIPHER_SUITE_BIP_GMAC_128:
+-      case WLAN_CIPHER_SUITE_BIP_GMAC_256:
+-              pn64 = atomic64_read(&key->u.aes_gmac.tx_pn);
+-              seq->ccmp.pn[5] = pn64;
+-              seq->ccmp.pn[4] = pn64 >> 8;
+-              seq->ccmp.pn[3] = pn64 >> 16;
+-              seq->ccmp.pn[2] = pn64 >> 24;
+-              seq->ccmp.pn[1] = pn64 >> 32;
+-              seq->ccmp.pn[0] = pn64 >> 40;
+-              break;
+-      case WLAN_CIPHER_SUITE_GCMP:
+-      case WLAN_CIPHER_SUITE_GCMP_256:
+-              pn64 = atomic64_read(&key->u.gcmp.tx_pn);
+-              seq->gcmp.pn[5] = pn64;
+-              seq->gcmp.pn[4] = pn64 >> 8;
+-              seq->gcmp.pn[3] = pn64 >> 16;
+-              seq->gcmp.pn[2] = pn64 >> 24;
+-              seq->gcmp.pn[1] = pn64 >> 32;
+-              seq->gcmp.pn[0] = pn64 >> 40;
+-              break;
+       default:
+               WARN_ON(1);
+       }
+@@ -887,7 +782,6 @@ void ieee80211_get_key_rx_seq(struct iee
+               seq->tkip.iv16 = key->u.tkip.rx[tid].iv16;
+               break;
+       case WLAN_CIPHER_SUITE_CCMP:
+-      case WLAN_CIPHER_SUITE_CCMP_256:
+               if (WARN_ON(tid < -1 || tid >= IEEE80211_NUM_TIDS))
+                       return;
+               if (tid < 0)
+@@ -897,29 +791,11 @@ void ieee80211_get_key_rx_seq(struct iee
+               memcpy(seq->ccmp.pn, pn, IEEE80211_CCMP_PN_LEN);
+               break;
+       case WLAN_CIPHER_SUITE_AES_CMAC:
+-      case WLAN_CIPHER_SUITE_BIP_CMAC_256:
+               if (WARN_ON(tid != 0))
+                       return;
+               pn = key->u.aes_cmac.rx_pn;
+               memcpy(seq->aes_cmac.pn, pn, IEEE80211_CMAC_PN_LEN);
+               break;
+-      case WLAN_CIPHER_SUITE_BIP_GMAC_128:
+-      case WLAN_CIPHER_SUITE_BIP_GMAC_256:
+-              if (WARN_ON(tid != 0))
+-                      return;
+-              pn = key->u.aes_gmac.rx_pn;
+-              memcpy(seq->aes_gmac.pn, pn, IEEE80211_GMAC_PN_LEN);
+-              break;
+-      case WLAN_CIPHER_SUITE_GCMP:
+-      case WLAN_CIPHER_SUITE_GCMP_256:
+-              if (WARN_ON(tid < -1 || tid >= IEEE80211_NUM_TIDS))
+-                      return;
+-              if (tid < 0)
+-                      pn = key->u.gcmp.rx_pn[IEEE80211_NUM_TIDS];
+-              else
+-                      pn = key->u.gcmp.rx_pn[tid];
+-              memcpy(seq->gcmp.pn, pn, IEEE80211_GCMP_PN_LEN);
+-              break;
+       }
+ }
+ EXPORT_SYMBOL(ieee80211_get_key_rx_seq);
+@@ -938,7 +814,6 @@ void ieee80211_set_key_tx_seq(struct iee
+               key->u.tkip.tx.iv16 = seq->tkip.iv16;
+               break;
+       case WLAN_CIPHER_SUITE_CCMP:
+-      case WLAN_CIPHER_SUITE_CCMP_256:
+               pn64 = (u64)seq->ccmp.pn[5] |
+                      ((u64)seq->ccmp.pn[4] << 8) |
+                      ((u64)seq->ccmp.pn[3] << 16) |
+@@ -948,7 +823,6 @@ void ieee80211_set_key_tx_seq(struct iee
+               atomic64_set(&key->u.ccmp.tx_pn, pn64);
+               break;
+       case WLAN_CIPHER_SUITE_AES_CMAC:
+-      case WLAN_CIPHER_SUITE_BIP_CMAC_256:
+               pn64 = (u64)seq->aes_cmac.pn[5] |
+                      ((u64)seq->aes_cmac.pn[4] << 8) |
+                      ((u64)seq->aes_cmac.pn[3] << 16) |
+@@ -957,26 +831,6 @@ void ieee80211_set_key_tx_seq(struct iee
+                      ((u64)seq->aes_cmac.pn[0] << 40);
+               atomic64_set(&key->u.aes_cmac.tx_pn, pn64);
+               break;
+-      case WLAN_CIPHER_SUITE_BIP_GMAC_128:
+-      case WLAN_CIPHER_SUITE_BIP_GMAC_256:
+-              pn64 = (u64)seq->aes_gmac.pn[5] |
+-                     ((u64)seq->aes_gmac.pn[4] << 8) |
+-                     ((u64)seq->aes_gmac.pn[3] << 16) |
+-                     ((u64)seq->aes_gmac.pn[2] << 24) |
+-                     ((u64)seq->aes_gmac.pn[1] << 32) |
+-                     ((u64)seq->aes_gmac.pn[0] << 40);
+-              atomic64_set(&key->u.aes_gmac.tx_pn, pn64);
+-              break;
+-      case WLAN_CIPHER_SUITE_GCMP:
+-      case WLAN_CIPHER_SUITE_GCMP_256:
+-              pn64 = (u64)seq->gcmp.pn[5] |
+-                     ((u64)seq->gcmp.pn[4] << 8) |
+-                     ((u64)seq->gcmp.pn[3] << 16) |
+-                     ((u64)seq->gcmp.pn[2] << 24) |
+-                     ((u64)seq->gcmp.pn[1] << 32) |
+-                     ((u64)seq->gcmp.pn[0] << 40);
+-              atomic64_set(&key->u.gcmp.tx_pn, pn64);
+-              break;
+       default:
+               WARN_ON(1);
+               break;
+@@ -1000,7 +854,6 @@ void ieee80211_set_key_rx_seq(struct iee
+               key->u.tkip.rx[tid].iv16 = seq->tkip.iv16;
+               break;
+       case WLAN_CIPHER_SUITE_CCMP:
+-      case WLAN_CIPHER_SUITE_CCMP_256:
+               if (WARN_ON(tid < -1 || tid >= IEEE80211_NUM_TIDS))
+                       return;
+               if (tid < 0)
+@@ -1010,29 +863,11 @@ void ieee80211_set_key_rx_seq(struct iee
+               memcpy(pn, seq->ccmp.pn, IEEE80211_CCMP_PN_LEN);
+               break;
+       case WLAN_CIPHER_SUITE_AES_CMAC:
+-      case WLAN_CIPHER_SUITE_BIP_CMAC_256:
+               if (WARN_ON(tid != 0))
+                       return;
+               pn = key->u.aes_cmac.rx_pn;
+               memcpy(pn, seq->aes_cmac.pn, IEEE80211_CMAC_PN_LEN);
+               break;
+-      case WLAN_CIPHER_SUITE_BIP_GMAC_128:
+-      case WLAN_CIPHER_SUITE_BIP_GMAC_256:
+-              if (WARN_ON(tid != 0))
+-                      return;
+-              pn = key->u.aes_gmac.rx_pn;
+-              memcpy(pn, seq->aes_gmac.pn, IEEE80211_GMAC_PN_LEN);
+-              break;
+-      case WLAN_CIPHER_SUITE_GCMP:
+-      case WLAN_CIPHER_SUITE_GCMP_256:
+-              if (WARN_ON(tid < -1 || tid >= IEEE80211_NUM_TIDS))
+-                      return;
+-              if (tid < 0)
+-                      pn = key->u.gcmp.rx_pn[IEEE80211_NUM_TIDS];
+-              else
+-                      pn = key->u.gcmp.rx_pn[tid];
+-              memcpy(pn, seq->gcmp.pn, IEEE80211_GCMP_PN_LEN);
+-              break;
+       default:
+               WARN_ON(1);
+               break;
+--- a/net/mac80211/key.h
++++ b/net/mac80211/key.h
+@@ -84,7 +84,7 @@ struct ieee80211_key {
+                        * Management frames.
+                        */
+                       u8 rx_pn[IEEE80211_NUM_TIDS + 1][IEEE80211_CCMP_PN_LEN];
+-                      struct crypto_aead *tfm;
++                      struct crypto_cipher *tfm;
+                       u32 replays; /* dot11RSNAStatsCCMPReplays */
+               } ccmp;
+               struct {
+@@ -95,24 +95,6 @@ struct ieee80211_key {
+                       u32 icverrors; /* dot11RSNAStatsCMACICVErrors */
+               } aes_cmac;
+               struct {
+-                      atomic64_t tx_pn;
+-                      u8 rx_pn[IEEE80211_GMAC_PN_LEN];
+-                      struct crypto_aead *tfm;
+-                      u32 replays; /* dot11RSNAStatsCMACReplays */
+-                      u32 icverrors; /* dot11RSNAStatsCMACICVErrors */
+-              } aes_gmac;
+-              struct {
+-                      atomic64_t tx_pn;
+-                      /* Last received packet number. The first
+-                       * IEEE80211_NUM_TIDS counters are used with Data
+-                       * frames and the last counter is used with Robust
+-                       * Management frames.
+-                       */
+-                      u8 rx_pn[IEEE80211_NUM_TIDS + 1][IEEE80211_GCMP_PN_LEN];
+-                      struct crypto_aead *tfm;
+-                      u32 replays; /* dot11RSNAStatsGCMPReplays */
+-              } gcmp;
+-              struct {
+                       /* generic cipher scheme */
+                       u8 rx_pn[IEEE80211_NUM_TIDS + 1][MAX_PN_LEN];
+               } gen;
+--- a/net/mac80211/main.c
++++ b/net/mac80211/main.c
+@@ -666,15 +666,9 @@ static int ieee80211_init_cipher_suites(
+               WLAN_CIPHER_SUITE_WEP104,
+               WLAN_CIPHER_SUITE_TKIP,
+               WLAN_CIPHER_SUITE_CCMP,
+-              WLAN_CIPHER_SUITE_CCMP_256,
+-              WLAN_CIPHER_SUITE_GCMP,
+-              WLAN_CIPHER_SUITE_GCMP_256,
+               /* keep last -- depends on hw flags! */
+-              WLAN_CIPHER_SUITE_AES_CMAC,
+-              WLAN_CIPHER_SUITE_BIP_CMAC_256,
+-              WLAN_CIPHER_SUITE_BIP_GMAC_128,
+-              WLAN_CIPHER_SUITE_BIP_GMAC_256,
++              WLAN_CIPHER_SUITE_AES_CMAC
+       };
+       if (local->hw.flags & IEEE80211_HW_SW_CRYPTO_CONTROL ||
+@@ -713,7 +707,7 @@ static int ieee80211_init_cipher_suites(
+               local->hw.wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
+               if (!have_mfp)
+-                      local->hw.wiphy->n_cipher_suites -= 4;
++                      local->hw.wiphy->n_cipher_suites--;
+               if (!have_wep) {
+                       local->hw.wiphy->cipher_suites += 2;
+@@ -730,42 +724,32 @@ static int ieee80211_init_cipher_suites(
+               /* Driver specifies cipher schemes only (but not cipher suites
+                * including the schemes)
+                *
+-               * We start counting ciphers defined by schemes, TKIP, CCMP,
+-               * CCMP-256, GCMP, and GCMP-256
++               * We start counting ciphers defined by schemes, TKIP and CCMP
+                */
+-              n_suites = local->hw.n_cipher_schemes + 5;
++              n_suites = local->hw.n_cipher_schemes + 2;
+               /* check if we have WEP40 and WEP104 */
+               if (have_wep)
+                       n_suites += 2;
+-              /* check if we have AES_CMAC, BIP-CMAC-256, BIP-GMAC-128,
+-               * BIP-GMAC-256
+-               */
++              /* check if we have AES_CMAC */
+               if (have_mfp)
+-                      n_suites += 4;
++                      n_suites++;
+               suites = kmalloc(sizeof(u32) * n_suites, GFP_KERNEL);
+               if (!suites)
+                       return -ENOMEM;
+               suites[w++] = WLAN_CIPHER_SUITE_CCMP;
+-              suites[w++] = WLAN_CIPHER_SUITE_CCMP_256;
+               suites[w++] = WLAN_CIPHER_SUITE_TKIP;
+-              suites[w++] = WLAN_CIPHER_SUITE_GCMP;
+-              suites[w++] = WLAN_CIPHER_SUITE_GCMP_256;
+               if (have_wep) {
+                       suites[w++] = WLAN_CIPHER_SUITE_WEP40;
+                       suites[w++] = WLAN_CIPHER_SUITE_WEP104;
+               }
+-              if (have_mfp) {
++              if (have_mfp)
+                       suites[w++] = WLAN_CIPHER_SUITE_AES_CMAC;
+-                      suites[w++] = WLAN_CIPHER_SUITE_BIP_CMAC_256;
+-                      suites[w++] = WLAN_CIPHER_SUITE_BIP_GMAC_128;
+-                      suites[w++] = WLAN_CIPHER_SUITE_BIP_GMAC_256;
+-              }
+               for (r = 0; r < local->hw.n_cipher_schemes; r++)
+                       suites[w++] = cs[r].cipher;
+--- a/net/mac80211/rx.c
++++ b/net/mac80211/rx.c
+@@ -647,7 +647,6 @@ static int ieee80211_get_mmie_keyidx(str
+ {
+       struct ieee80211_mgmt *hdr = (struct ieee80211_mgmt *) skb->data;
+       struct ieee80211_mmie *mmie;
+-      struct ieee80211_mmie_16 *mmie16;
+       if (skb->len < 24 + sizeof(*mmie) || !is_multicast_ether_addr(hdr->da))
+               return -1;
+@@ -657,18 +656,11 @@ static int ieee80211_get_mmie_keyidx(str
+       mmie = (struct ieee80211_mmie *)
+               (skb->data + skb->len - sizeof(*mmie));
+-      if (mmie->element_id == WLAN_EID_MMIE &&
+-          mmie->length == sizeof(*mmie) - 2)
+-              return le16_to_cpu(mmie->key_id);
+-
+-      mmie16 = (struct ieee80211_mmie_16 *)
+-              (skb->data + skb->len - sizeof(*mmie16));
+-      if (skb->len >= 24 + sizeof(*mmie16) &&
+-          mmie16->element_id == WLAN_EID_MMIE &&
+-          mmie16->length == sizeof(*mmie16) - 2)
+-              return le16_to_cpu(mmie16->key_id);
++      if (mmie->element_id != WLAN_EID_MMIE ||
++          mmie->length != sizeof(*mmie) - 2)
++              return -1;
+-      return -1;
++      return le16_to_cpu(mmie->key_id);
+ }
+ static int iwl80211_get_cs_keyid(const struct ieee80211_cipher_scheme *cs,
+@@ -1658,27 +1650,11 @@ ieee80211_rx_h_decrypt(struct ieee80211_
+               result = ieee80211_crypto_tkip_decrypt(rx);
+               break;
+       case WLAN_CIPHER_SUITE_CCMP:
+-              result = ieee80211_crypto_ccmp_decrypt(
+-                      rx, IEEE80211_CCMP_MIC_LEN);
+-              break;
+-      case WLAN_CIPHER_SUITE_CCMP_256:
+-              result = ieee80211_crypto_ccmp_decrypt(
+-                      rx, IEEE80211_CCMP_256_MIC_LEN);
++              result = ieee80211_crypto_ccmp_decrypt(rx);
+               break;
+       case WLAN_CIPHER_SUITE_AES_CMAC:
+               result = ieee80211_crypto_aes_cmac_decrypt(rx);
+               break;
+-      case WLAN_CIPHER_SUITE_BIP_CMAC_256:
+-              result = ieee80211_crypto_aes_cmac_256_decrypt(rx);
+-              break;
+-      case WLAN_CIPHER_SUITE_BIP_GMAC_128:
+-      case WLAN_CIPHER_SUITE_BIP_GMAC_256:
+-              result = ieee80211_crypto_aes_gmac_decrypt(rx);
+-              break;
+-      case WLAN_CIPHER_SUITE_GCMP:
+-      case WLAN_CIPHER_SUITE_GCMP_256:
+-              result = ieee80211_crypto_gcmp_decrypt(rx);
+-              break;
+       default:
+               result = ieee80211_crypto_hw_decrypt(rx);
+       }
+@@ -1805,9 +1781,7 @@ ieee80211_rx_h_defragment(struct ieee802
+               /* This is the first fragment of a new frame. */
+               entry = ieee80211_reassemble_add(rx->sdata, frag, seq,
+                                                rx->seqno_idx, &(rx->skb));
+-              if (rx->key &&
+-                  (rx->key->conf.cipher == WLAN_CIPHER_SUITE_CCMP ||
+-                   rx->key->conf.cipher == WLAN_CIPHER_SUITE_CCMP_256) &&
++              if (rx->key && rx->key->conf.cipher == WLAN_CIPHER_SUITE_CCMP &&
+                   ieee80211_has_protected(fc)) {
+                       int queue = rx->security_idx;
+                       /* Store CCMP PN so that we can verify that the next
+@@ -1836,9 +1810,7 @@ ieee80211_rx_h_defragment(struct ieee802
+               int i;
+               u8 pn[IEEE80211_CCMP_PN_LEN], *rpn;
+               int queue;
+-              if (!rx->key ||
+-                  (rx->key->conf.cipher != WLAN_CIPHER_SUITE_CCMP &&
+-                   rx->key->conf.cipher != WLAN_CIPHER_SUITE_CCMP_256))
++              if (!rx->key || rx->key->conf.cipher != WLAN_CIPHER_SUITE_CCMP)
+                       return RX_DROP_UNUSABLE;
+               memcpy(pn, entry->last_pn, IEEE80211_CCMP_PN_LEN);
+               for (i = IEEE80211_CCMP_PN_LEN - 1; i >= 0; i--) {
+--- a/net/mac80211/tx.c
++++ b/net/mac80211/tx.c
+@@ -626,9 +626,6 @@ ieee80211_tx_h_select_key(struct ieee802
+                               tx->key = NULL;
+                       break;
+               case WLAN_CIPHER_SUITE_CCMP:
+-              case WLAN_CIPHER_SUITE_CCMP_256:
+-              case WLAN_CIPHER_SUITE_GCMP:
+-              case WLAN_CIPHER_SUITE_GCMP_256:
+                       if (!ieee80211_is_data_present(hdr->frame_control) &&
+                           !ieee80211_use_mfp(hdr->frame_control, tx->sta,
+                                              tx->skb))
+@@ -639,9 +636,6 @@ ieee80211_tx_h_select_key(struct ieee802
+                                       ieee80211_is_mgmt(hdr->frame_control);
+                       break;
+               case WLAN_CIPHER_SUITE_AES_CMAC:
+-              case WLAN_CIPHER_SUITE_BIP_CMAC_256:
+-              case WLAN_CIPHER_SUITE_BIP_GMAC_128:
+-              case WLAN_CIPHER_SUITE_BIP_GMAC_256:
+                       if (!ieee80211_is_mgmt(hdr->frame_control))
+                               tx->key = NULL;
+                       break;
+@@ -1017,21 +1011,9 @@ ieee80211_tx_h_encrypt(struct ieee80211_
+       case WLAN_CIPHER_SUITE_TKIP:
+               return ieee80211_crypto_tkip_encrypt(tx);
+       case WLAN_CIPHER_SUITE_CCMP:
+-              return ieee80211_crypto_ccmp_encrypt(
+-                      tx, IEEE80211_CCMP_MIC_LEN);
+-      case WLAN_CIPHER_SUITE_CCMP_256:
+-              return ieee80211_crypto_ccmp_encrypt(
+-                      tx, IEEE80211_CCMP_256_MIC_LEN);
++              return ieee80211_crypto_ccmp_encrypt(tx);
+       case WLAN_CIPHER_SUITE_AES_CMAC:
+               return ieee80211_crypto_aes_cmac_encrypt(tx);
+-      case WLAN_CIPHER_SUITE_BIP_CMAC_256:
+-              return ieee80211_crypto_aes_cmac_256_encrypt(tx);
+-      case WLAN_CIPHER_SUITE_BIP_GMAC_128:
+-      case WLAN_CIPHER_SUITE_BIP_GMAC_256:
+-              return ieee80211_crypto_aes_gmac_encrypt(tx);
+-      case WLAN_CIPHER_SUITE_GCMP:
+-      case WLAN_CIPHER_SUITE_GCMP_256:
+-              return ieee80211_crypto_gcmp_encrypt(tx);
+       default:
+               return ieee80211_crypto_hw_encrypt(tx);
+       }
+--- a/net/mac80211/wpa.c
++++ b/net/mac80211/wpa.c
+@@ -22,8 +22,6 @@
+ #include "tkip.h"
+ #include "aes_ccm.h"
+ #include "aes_cmac.h"
+-#include "aes_gmac.h"
+-#include "aes_gcm.h"
+ #include "wpa.h"
+ ieee80211_tx_result
+@@ -304,15 +302,22 @@ ieee80211_crypto_tkip_decrypt(struct iee
+ }
+-static void ccmp_special_blocks(struct sk_buff *skb, u8 *pn, u8 *b_0, u8 *aad)
++static void ccmp_special_blocks(struct sk_buff *skb, u8 *pn, u8 *scratch,
++                              int encrypted)
+ {
+       __le16 mask_fc;
+       int a4_included, mgmt;
+       u8 qos_tid;
+-      u16 len_a;
++      u8 *b_0, *aad;
++      u16 data_len, len_a;
+       unsigned int hdrlen;
+       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
++      memset(scratch, 0, 6 * AES_BLOCK_SIZE);
++
++      b_0 = scratch + 3 * AES_BLOCK_SIZE;
++      aad = scratch + 4 * AES_BLOCK_SIZE;
++
+       /*
+        * Mask FC: zero subtype b4 b5 b6 (if not mgmt)
+        * Retry, PwrMgt, MoreData; set Protected
+@@ -334,21 +339,20 @@ static void ccmp_special_blocks(struct s
+       else
+               qos_tid = 0;
+-      /* In CCM, the initial vectors (IV) used for CTR mode encryption and CBC
+-       * mode authentication are not allowed to collide, yet both are derived
+-       * from this vector b_0. We only set L := 1 here to indicate that the
+-       * data size can be represented in (L+1) bytes. The CCM layer will take
+-       * care of storing the data length in the top (L+1) bytes and setting
+-       * and clearing the other bits as is required to derive the two IVs.
+-       */
+-      b_0[0] = 0x1;
++      data_len = skb->len - hdrlen - IEEE80211_CCMP_HDR_LEN;
++      if (encrypted)
++              data_len -= IEEE80211_CCMP_MIC_LEN;
++      /* First block, b_0 */
++      b_0[0] = 0x59; /* flags: Adata: 1, M: 011, L: 001 */
+       /* Nonce: Nonce Flags | A2 | PN
+        * Nonce Flags: Priority (b0..b3) | Management (b4) | Reserved (b5..b7)
+        */
+       b_0[1] = qos_tid | (mgmt << 4);
+       memcpy(&b_0[2], hdr->addr2, ETH_ALEN);
+       memcpy(&b_0[8], pn, IEEE80211_CCMP_PN_LEN);
++      /* l(m) */
++      put_unaligned_be16(data_len, &b_0[14]);
+       /* AAD (extra authenticate-only data) / masked 802.11 header
+        * FC | A1 | A2 | A3 | SC | [A4] | [QC] */
+@@ -395,8 +399,7 @@ static inline void ccmp_hdr2pn(u8 *pn, u
+ }
+-static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb,
+-                          unsigned int mic_len)
++static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
+ {
+       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+       struct ieee80211_key *key = tx->key;
+@@ -405,8 +408,7 @@ static int ccmp_encrypt_skb(struct ieee8
+       u8 *pos;
+       u8 pn[6];
+       u64 pn64;
+-      u8 aad[2 * AES_BLOCK_SIZE];
+-      u8 b_0[AES_BLOCK_SIZE];
++      u8 scratch[6 * AES_BLOCK_SIZE];
+       if (info->control.hw_key &&
+           !(info->control.hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_IV) &&
+@@ -427,7 +429,7 @@ static int ccmp_encrypt_skb(struct ieee8
+       if (info->control.hw_key)
+               tail = 0;
+       else
+-              tail = mic_len;
++              tail = IEEE80211_CCMP_MIC_LEN;
+       if (WARN_ON(skb_tailroom(skb) < tail ||
+                   skb_headroom(skb) < IEEE80211_CCMP_HDR_LEN))
+@@ -460,24 +462,23 @@ static int ccmp_encrypt_skb(struct ieee8
+               return 0;
+       pos += IEEE80211_CCMP_HDR_LEN;
+-      ccmp_special_blocks(skb, pn, b_0, aad);
+-      ieee80211_aes_ccm_encrypt(key->u.ccmp.tfm, b_0, aad, pos, len,
+-                                skb_put(skb, mic_len), mic_len);
++      ccmp_special_blocks(skb, pn, scratch, 0);
++      ieee80211_aes_ccm_encrypt(key->u.ccmp.tfm, scratch, pos, len,
++                                pos, skb_put(skb, IEEE80211_CCMP_MIC_LEN));
+       return 0;
+ }
+ ieee80211_tx_result
+-ieee80211_crypto_ccmp_encrypt(struct ieee80211_tx_data *tx,
+-                            unsigned int mic_len)
++ieee80211_crypto_ccmp_encrypt(struct ieee80211_tx_data *tx)
+ {
+       struct sk_buff *skb;
+       ieee80211_tx_set_protected(tx);
+       skb_queue_walk(&tx->skbs, skb) {
+-              if (ccmp_encrypt_skb(tx, skb, mic_len) < 0)
++              if (ccmp_encrypt_skb(tx, skb) < 0)
+                       return TX_DROP;
+       }
+@@ -486,8 +487,7 @@ ieee80211_crypto_ccmp_encrypt(struct iee
+ ieee80211_rx_result
+-ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx,
+-                            unsigned int mic_len)
++ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx)
+ {
+       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data;
+       int hdrlen;
+@@ -504,7 +504,8 @@ ieee80211_crypto_ccmp_decrypt(struct iee
+           !ieee80211_is_robust_mgmt_frame(skb))
+               return RX_CONTINUE;
+-      data_len = skb->len - hdrlen - IEEE80211_CCMP_HDR_LEN - mic_len;
++      data_len = skb->len - hdrlen - IEEE80211_CCMP_HDR_LEN -
++                 IEEE80211_CCMP_MIC_LEN;
+       if (!rx->sta || data_len < 0)
+               return RX_DROP_UNUSABLE;
+@@ -526,23 +527,23 @@ ieee80211_crypto_ccmp_decrypt(struct iee
+       }
+       if (!(status->flag & RX_FLAG_DECRYPTED)) {
+-              u8 aad[2 * AES_BLOCK_SIZE];
+-              u8 b_0[AES_BLOCK_SIZE];
++              u8 scratch[6 * AES_BLOCK_SIZE];
+               /* hardware didn't decrypt/verify MIC */
+-              ccmp_special_blocks(skb, pn, b_0, aad);
++              ccmp_special_blocks(skb, pn, scratch, 1);
+               if (ieee80211_aes_ccm_decrypt(
+-                          key->u.ccmp.tfm, b_0, aad,
++                          key->u.ccmp.tfm, scratch,
+                           skb->data + hdrlen + IEEE80211_CCMP_HDR_LEN,
+                           data_len,
+-                          skb->data + skb->len - mic_len, mic_len))
++                          skb->data + skb->len - IEEE80211_CCMP_MIC_LEN,
++                          skb->data + hdrlen + IEEE80211_CCMP_HDR_LEN))
+                       return RX_DROP_UNUSABLE;
+       }
+       memcpy(key->u.ccmp.rx_pn[queue], pn, IEEE80211_CCMP_PN_LEN);
+       /* Remove CCMP header and MIC */
+-      if (pskb_trim(skb, skb->len - mic_len))
++      if (pskb_trim(skb, skb->len - IEEE80211_CCMP_MIC_LEN))
+               return RX_DROP_UNUSABLE;
+       memmove(skb->data + IEEE80211_CCMP_HDR_LEN, skb->data, hdrlen);
+       skb_pull(skb, IEEE80211_CCMP_HDR_LEN);
+@@ -550,229 +551,6 @@ ieee80211_crypto_ccmp_decrypt(struct iee
+       return RX_CONTINUE;
+ }
+-static void gcmp_special_blocks(struct sk_buff *skb, u8 *pn, u8 *j_0, u8 *aad)
+-{
+-      __le16 mask_fc;
+-      u8 qos_tid;
+-      struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+-
+-      memcpy(j_0, hdr->addr2, ETH_ALEN);
+-      memcpy(&j_0[ETH_ALEN], pn, IEEE80211_GCMP_PN_LEN);
+-      j_0[13] = 0;
+-      j_0[14] = 0;
+-      j_0[AES_BLOCK_SIZE - 1] = 0x01;
+-
+-      /* AAD (extra authenticate-only data) / masked 802.11 header
+-       * FC | A1 | A2 | A3 | SC | [A4] | [QC]
+-       */
+-      put_unaligned_be16(ieee80211_hdrlen(hdr->frame_control) - 2, &aad[0]);
+-      /* Mask FC: zero subtype b4 b5 b6 (if not mgmt)
+-       * Retry, PwrMgt, MoreData; set Protected
+-       */
+-      mask_fc = hdr->frame_control;
+-      mask_fc &= ~cpu_to_le16(IEEE80211_FCTL_RETRY |
+-                              IEEE80211_FCTL_PM | IEEE80211_FCTL_MOREDATA);
+-      if (!ieee80211_is_mgmt(hdr->frame_control))
+-              mask_fc &= ~cpu_to_le16(0x0070);
+-      mask_fc |= cpu_to_le16(IEEE80211_FCTL_PROTECTED);
+-
+-      put_unaligned(mask_fc, (__le16 *)&aad[2]);
+-      memcpy(&aad[4], &hdr->addr1, 3 * ETH_ALEN);
+-
+-      /* Mask Seq#, leave Frag# */
+-      aad[22] = *((u8 *)&hdr->seq_ctrl) & 0x0f;
+-      aad[23] = 0;
+-
+-      if (ieee80211_is_data_qos(hdr->frame_control))
+-              qos_tid = *ieee80211_get_qos_ctl(hdr) &
+-                      IEEE80211_QOS_CTL_TID_MASK;
+-      else
+-              qos_tid = 0;
+-
+-      if (ieee80211_has_a4(hdr->frame_control)) {
+-              memcpy(&aad[24], hdr->addr4, ETH_ALEN);
+-              aad[30] = qos_tid;
+-              aad[31] = 0;
+-      } else {
+-              memset(&aad[24], 0, ETH_ALEN + IEEE80211_QOS_CTL_LEN);
+-              aad[24] = qos_tid;
+-      }
+-}
+-
+-static inline void gcmp_pn2hdr(u8 *hdr, const u8 *pn, int key_id)
+-{
+-      hdr[0] = pn[5];
+-      hdr[1] = pn[4];
+-      hdr[2] = 0;
+-      hdr[3] = 0x20 | (key_id << 6);
+-      hdr[4] = pn[3];
+-      hdr[5] = pn[2];
+-      hdr[6] = pn[1];
+-      hdr[7] = pn[0];
+-}
+-
+-static inline void gcmp_hdr2pn(u8 *pn, const u8 *hdr)
+-{
+-      pn[0] = hdr[7];
+-      pn[1] = hdr[6];
+-      pn[2] = hdr[5];
+-      pn[3] = hdr[4];
+-      pn[4] = hdr[1];
+-      pn[5] = hdr[0];
+-}
+-
+-static int gcmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
+-{
+-      struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+-      struct ieee80211_key *key = tx->key;
+-      struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+-      int hdrlen, len, tail;
+-      u8 *pos;
+-      u8 pn[6];
+-      u64 pn64;
+-      u8 aad[2 * AES_BLOCK_SIZE];
+-      u8 j_0[AES_BLOCK_SIZE];
+-
+-      if (info->control.hw_key &&
+-          !(info->control.hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_IV) &&
+-          !(info->control.hw_key->flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE) &&
+-          !((info->control.hw_key->flags &
+-             IEEE80211_KEY_FLAG_GENERATE_IV_MGMT) &&
+-            ieee80211_is_mgmt(hdr->frame_control))) {
+-              /* hwaccel has no need for preallocated room for GCMP
+-               * header or MIC fields
+-               */
+-              return 0;
+-      }
+-
+-      hdrlen = ieee80211_hdrlen(hdr->frame_control);
+-      len = skb->len - hdrlen;
+-
+-      if (info->control.hw_key)
+-              tail = 0;
+-      else
+-              tail = IEEE80211_GCMP_MIC_LEN;
+-
+-      if (WARN_ON(skb_tailroom(skb) < tail ||
+-                  skb_headroom(skb) < IEEE80211_GCMP_HDR_LEN))
+-              return -1;
+-
+-      pos = skb_push(skb, IEEE80211_GCMP_HDR_LEN);
+-      memmove(pos, pos + IEEE80211_GCMP_HDR_LEN, hdrlen);
+-      skb_set_network_header(skb, skb_network_offset(skb) +
+-                                  IEEE80211_GCMP_HDR_LEN);
+-
+-      /* the HW only needs room for the IV, but not the actual IV */
+-      if (info->control.hw_key &&
+-          (info->control.hw_key->flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE))
+-              return 0;
+-
+-      hdr = (struct ieee80211_hdr *)pos;
+-      pos += hdrlen;
+-
+-      pn64 = atomic64_inc_return(&key->u.gcmp.tx_pn);
+-
+-      pn[5] = pn64;
+-      pn[4] = pn64 >> 8;
+-      pn[3] = pn64 >> 16;
+-      pn[2] = pn64 >> 24;
+-      pn[1] = pn64 >> 32;
+-      pn[0] = pn64 >> 40;
+-
+-      gcmp_pn2hdr(pos, pn, key->conf.keyidx);
+-
+-      /* hwaccel - with software GCMP header */
+-      if (info->control.hw_key)
+-              return 0;
+-
+-      pos += IEEE80211_GCMP_HDR_LEN;
+-      gcmp_special_blocks(skb, pn, j_0, aad);
+-      ieee80211_aes_gcm_encrypt(key->u.gcmp.tfm, j_0, aad, pos, len,
+-                                skb_put(skb, IEEE80211_GCMP_MIC_LEN));
+-
+-      return 0;
+-}
+-
+-ieee80211_tx_result
+-ieee80211_crypto_gcmp_encrypt(struct ieee80211_tx_data *tx)
+-{
+-      struct sk_buff *skb;
+-
+-      ieee80211_tx_set_protected(tx);
+-
+-      skb_queue_walk(&tx->skbs, skb) {
+-              if (gcmp_encrypt_skb(tx, skb) < 0)
+-                      return TX_DROP;
+-      }
+-
+-      return TX_CONTINUE;
+-}
+-
+-ieee80211_rx_result
+-ieee80211_crypto_gcmp_decrypt(struct ieee80211_rx_data *rx)
+-{
+-      struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data;
+-      int hdrlen;
+-      struct ieee80211_key *key = rx->key;
+-      struct sk_buff *skb = rx->skb;
+-      struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
+-      u8 pn[IEEE80211_GCMP_PN_LEN];
+-      int data_len;
+-      int queue;
+-
+-      hdrlen = ieee80211_hdrlen(hdr->frame_control);
+-
+-      if (!ieee80211_is_data(hdr->frame_control) &&
+-          !ieee80211_is_robust_mgmt_frame(skb))
+-              return RX_CONTINUE;
+-
+-      data_len = skb->len - hdrlen - IEEE80211_GCMP_HDR_LEN -
+-                 IEEE80211_GCMP_MIC_LEN;
+-      if (!rx->sta || data_len < 0)
+-              return RX_DROP_UNUSABLE;
+-
+-      if (status->flag & RX_FLAG_DECRYPTED) {
+-              if (!pskb_may_pull(rx->skb, hdrlen + IEEE80211_GCMP_HDR_LEN))
+-                      return RX_DROP_UNUSABLE;
+-      } else {
+-              if (skb_linearize(rx->skb))
+-                      return RX_DROP_UNUSABLE;
+-      }
+-
+-      gcmp_hdr2pn(pn, skb->data + hdrlen);
+-
+-      queue = rx->security_idx;
+-
+-      if (memcmp(pn, key->u.gcmp.rx_pn[queue], IEEE80211_GCMP_PN_LEN) <= 0) {
+-              key->u.gcmp.replays++;
+-              return RX_DROP_UNUSABLE;
+-      }
+-
+-      if (!(status->flag & RX_FLAG_DECRYPTED)) {
+-              u8 aad[2 * AES_BLOCK_SIZE];
+-              u8 j_0[AES_BLOCK_SIZE];
+-              /* hardware didn't decrypt/verify MIC */
+-              gcmp_special_blocks(skb, pn, j_0, aad);
+-
+-              if (ieee80211_aes_gcm_decrypt(
+-                          key->u.gcmp.tfm, j_0, aad,
+-                          skb->data + hdrlen + IEEE80211_GCMP_HDR_LEN,
+-                          data_len,
+-                          skb->data + skb->len - IEEE80211_GCMP_MIC_LEN))
+-                      return RX_DROP_UNUSABLE;
+-      }
+-
+-      memcpy(key->u.gcmp.rx_pn[queue], pn, IEEE80211_GCMP_PN_LEN);
+-
+-      /* Remove GCMP header and MIC */
+-      if (pskb_trim(skb, skb->len - IEEE80211_GCMP_MIC_LEN))
+-              return RX_DROP_UNUSABLE;
+-      memmove(skb->data + IEEE80211_GCMP_HDR_LEN, skb->data, hdrlen);
+-      skb_pull(skb, IEEE80211_GCMP_HDR_LEN);
+-
+-      return RX_CONTINUE;
+-}
+-
+ static ieee80211_tx_result
+ ieee80211_crypto_cs_encrypt(struct ieee80211_tx_data *tx,
+                           struct sk_buff *skb)
+@@ -956,48 +734,6 @@ ieee80211_crypto_aes_cmac_encrypt(struct
+       return TX_CONTINUE;
+ }
+-ieee80211_tx_result
+-ieee80211_crypto_aes_cmac_256_encrypt(struct ieee80211_tx_data *tx)
+-{
+-      struct sk_buff *skb;
+-      struct ieee80211_tx_info *info;
+-      struct ieee80211_key *key = tx->key;
+-      struct ieee80211_mmie_16 *mmie;
+-      u8 aad[20];
+-      u64 pn64;
+-
+-      if (WARN_ON(skb_queue_len(&tx->skbs) != 1))
+-              return TX_DROP;
+-
+-      skb = skb_peek(&tx->skbs);
+-
+-      info = IEEE80211_SKB_CB(skb);
+-
+-      if (info->control.hw_key)
+-              return TX_CONTINUE;
+-
+-      if (WARN_ON(skb_tailroom(skb) < sizeof(*mmie)))
+-              return TX_DROP;
+-
+-      mmie = (struct ieee80211_mmie_16 *)skb_put(skb, sizeof(*mmie));
+-      mmie->element_id = WLAN_EID_MMIE;
+-      mmie->length = sizeof(*mmie) - 2;
+-      mmie->key_id = cpu_to_le16(key->conf.keyidx);
+-
+-      /* PN = PN + 1 */
+-      pn64 = atomic64_inc_return(&key->u.aes_cmac.tx_pn);
+-
+-      bip_ipn_set64(mmie->sequence_number, pn64);
+-
+-      bip_aad(skb, aad);
+-
+-      /* MIC = AES-256-CMAC(IGTK, AAD || Management Frame Body || MMIE, 128)
+-       */
+-      ieee80211_aes_cmac_256(key->u.aes_cmac.tfm, aad,
+-                             skb->data + 24, skb->len - 24, mmie->mic);
+-
+-      return TX_CONTINUE;
+-}
+ ieee80211_rx_result
+ ieee80211_crypto_aes_cmac_decrypt(struct ieee80211_rx_data *rx)
+@@ -1045,160 +781,6 @@ ieee80211_crypto_aes_cmac_decrypt(struct
+       /* Remove MMIE */
+       skb_trim(skb, skb->len - sizeof(*mmie));
+-
+-      return RX_CONTINUE;
+-}
+-
+-ieee80211_rx_result
+-ieee80211_crypto_aes_cmac_256_decrypt(struct ieee80211_rx_data *rx)
+-{
+-      struct sk_buff *skb = rx->skb;
+-      struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
+-      struct ieee80211_key *key = rx->key;
+-      struct ieee80211_mmie_16 *mmie;
+-      u8 aad[20], mic[16], ipn[6];
+-      struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+-
+-      if (!ieee80211_is_mgmt(hdr->frame_control))
+-              return RX_CONTINUE;
+-
+-      /* management frames are already linear */
+-
+-      if (skb->len < 24 + sizeof(*mmie))
+-              return RX_DROP_UNUSABLE;
+-
+-      mmie = (struct ieee80211_mmie_16 *)
+-              (skb->data + skb->len - sizeof(*mmie));
+-      if (mmie->element_id != WLAN_EID_MMIE ||
+-          mmie->length != sizeof(*mmie) - 2)
+-              return RX_DROP_UNUSABLE; /* Invalid MMIE */
+-
+-      bip_ipn_swap(ipn, mmie->sequence_number);
+-
+-      if (memcmp(ipn, key->u.aes_cmac.rx_pn, 6) <= 0) {
+-              key->u.aes_cmac.replays++;
+-              return RX_DROP_UNUSABLE;
+-      }
+-
+-      if (!(status->flag & RX_FLAG_DECRYPTED)) {
+-              /* hardware didn't decrypt/verify MIC */
+-              bip_aad(skb, aad);
+-              ieee80211_aes_cmac_256(key->u.aes_cmac.tfm, aad,
+-                                     skb->data + 24, skb->len - 24, mic);
+-              if (memcmp(mic, mmie->mic, sizeof(mmie->mic)) != 0) {
+-                      key->u.aes_cmac.icverrors++;
+-                      return RX_DROP_UNUSABLE;
+-              }
+-      }
+-
+-      memcpy(key->u.aes_cmac.rx_pn, ipn, 6);
+-
+-      /* Remove MMIE */
+-      skb_trim(skb, skb->len - sizeof(*mmie));
+-
+-      return RX_CONTINUE;
+-}
+-
+-ieee80211_tx_result
+-ieee80211_crypto_aes_gmac_encrypt(struct ieee80211_tx_data *tx)
+-{
+-      struct sk_buff *skb;
+-      struct ieee80211_tx_info *info;
+-      struct ieee80211_key *key = tx->key;
+-      struct ieee80211_mmie_16 *mmie;
+-      struct ieee80211_hdr *hdr;
+-      u8 aad[20];
+-      u64 pn64;
+-      u8 nonce[12];
+-
+-      if (WARN_ON(skb_queue_len(&tx->skbs) != 1))
+-              return TX_DROP;
+-
+-      skb = skb_peek(&tx->skbs);
+-
+-      info = IEEE80211_SKB_CB(skb);
+-
+-      if (info->control.hw_key)
+-              return TX_CONTINUE;
+-
+-      if (WARN_ON(skb_tailroom(skb) < sizeof(*mmie)))
+-              return TX_DROP;
+-
+-      mmie = (struct ieee80211_mmie_16 *)skb_put(skb, sizeof(*mmie));
+-      mmie->element_id = WLAN_EID_MMIE;
+-      mmie->length = sizeof(*mmie) - 2;
+-      mmie->key_id = cpu_to_le16(key->conf.keyidx);
+-
+-      /* PN = PN + 1 */
+-      pn64 = atomic64_inc_return(&key->u.aes_gmac.tx_pn);
+-
+-      bip_ipn_set64(mmie->sequence_number, pn64);
+-
+-      bip_aad(skb, aad);
+-
+-      hdr = (struct ieee80211_hdr *)skb->data;
+-      memcpy(nonce, hdr->addr2, ETH_ALEN);
+-      bip_ipn_swap(nonce + ETH_ALEN, mmie->sequence_number);
+-
+-      /* MIC = AES-GMAC(IGTK, AAD || Management Frame Body || MMIE, 128) */
+-      if (ieee80211_aes_gmac(key->u.aes_gmac.tfm, aad, nonce,
+-                             skb->data + 24, skb->len - 24, mmie->mic) < 0)
+-              return TX_DROP;
+-
+-      return TX_CONTINUE;
+-}
+-
+-ieee80211_rx_result
+-ieee80211_crypto_aes_gmac_decrypt(struct ieee80211_rx_data *rx)
+-{
+-      struct sk_buff *skb = rx->skb;
+-      struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
+-      struct ieee80211_key *key = rx->key;
+-      struct ieee80211_mmie_16 *mmie;
+-      u8 aad[20], mic[16], ipn[6], nonce[12];
+-      struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+-
+-      if (!ieee80211_is_mgmt(hdr->frame_control))
+-              return RX_CONTINUE;
+-
+-      /* management frames are already linear */
+-
+-      if (skb->len < 24 + sizeof(*mmie))
+-              return RX_DROP_UNUSABLE;
+-
+-      mmie = (struct ieee80211_mmie_16 *)
+-              (skb->data + skb->len - sizeof(*mmie));
+-      if (mmie->element_id != WLAN_EID_MMIE ||
+-          mmie->length != sizeof(*mmie) - 2)
+-              return RX_DROP_UNUSABLE; /* Invalid MMIE */
+-
+-      bip_ipn_swap(ipn, mmie->sequence_number);
+-
+-      if (memcmp(ipn, key->u.aes_gmac.rx_pn, 6) <= 0) {
+-              key->u.aes_gmac.replays++;
+-              return RX_DROP_UNUSABLE;
+-      }
+-
+-      if (!(status->flag & RX_FLAG_DECRYPTED)) {
+-              /* hardware didn't decrypt/verify MIC */
+-              bip_aad(skb, aad);
+-
+-              memcpy(nonce, hdr->addr2, ETH_ALEN);
+-              memcpy(nonce + ETH_ALEN, ipn, 6);
+-
+-              if (ieee80211_aes_gmac(key->u.aes_gmac.tfm, aad, nonce,
+-                                     skb->data + 24, skb->len - 24,
+-                                     mic) < 0 ||
+-                  memcmp(mic, mmie->mic, sizeof(mmie->mic)) != 0) {
+-                      key->u.aes_gmac.icverrors++;
+-                      return RX_DROP_UNUSABLE;
+-              }
+-      }
+-
+-      memcpy(key->u.aes_gmac.rx_pn, ipn, 6);
+-
+-      /* Remove MMIE */
+-      skb_trim(skb, skb->len - sizeof(*mmie));
+       return RX_CONTINUE;
+ }
+--- a/net/mac80211/wpa.h
++++ b/net/mac80211/wpa.h
+@@ -24,32 +24,17 @@ ieee80211_rx_result
+ ieee80211_crypto_tkip_decrypt(struct ieee80211_rx_data *rx);
+ ieee80211_tx_result
+-ieee80211_crypto_ccmp_encrypt(struct ieee80211_tx_data *tx,
+-                            unsigned int mic_len);
++ieee80211_crypto_ccmp_encrypt(struct ieee80211_tx_data *tx);
+ ieee80211_rx_result
+-ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx,
+-                            unsigned int mic_len);
++ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx);
+ ieee80211_tx_result
+ ieee80211_crypto_aes_cmac_encrypt(struct ieee80211_tx_data *tx);
+-ieee80211_tx_result
+-ieee80211_crypto_aes_cmac_256_encrypt(struct ieee80211_tx_data *tx);
+ ieee80211_rx_result
+ ieee80211_crypto_aes_cmac_decrypt(struct ieee80211_rx_data *rx);
+-ieee80211_rx_result
+-ieee80211_crypto_aes_cmac_256_decrypt(struct ieee80211_rx_data *rx);
+-ieee80211_tx_result
+-ieee80211_crypto_aes_gmac_encrypt(struct ieee80211_tx_data *tx);
+-ieee80211_rx_result
+-ieee80211_crypto_aes_gmac_decrypt(struct ieee80211_rx_data *rx);
+ ieee80211_tx_result
+ ieee80211_crypto_hw_encrypt(struct ieee80211_tx_data *tx);
+ ieee80211_rx_result
+ ieee80211_crypto_hw_decrypt(struct ieee80211_rx_data *rx);
+-ieee80211_tx_result
+-ieee80211_crypto_gcmp_encrypt(struct ieee80211_tx_data *tx);
+-ieee80211_rx_result
+-ieee80211_crypto_gcmp_decrypt(struct ieee80211_rx_data *rx);
+-
+ #endif /* WPA_H */
diff --git a/package/kernel/mac80211/patches/100-revert_aes_ccm_port.patch b/package/kernel/mac80211/patches/100-revert_aes_ccm_port.patch
deleted file mode 100644 (file)
index cb14c0b..0000000
+++ /dev/null
@@ -1,347 +0,0 @@
---- a/net/mac80211/Kconfig
-+++ b/net/mac80211/Kconfig
-@@ -5,7 +5,6 @@ config MAC80211
-       depends on CRYPTO
-       depends on CRYPTO_ARC4
-       depends on CRYPTO_AES
--      select BACKPORT_CRYPTO_CCM
-       depends on CRC32
-       select BACKPORT_AVERAGE
-       ---help---
---- a/net/mac80211/aes_ccm.c
-+++ b/net/mac80211/aes_ccm.c
-@@ -2,8 +2,6 @@
-  * Copyright 2003-2004, Instant802 Networks, Inc.
-  * Copyright 2005-2006, Devicescape Software, Inc.
-  *
-- * Rewrite: Copyright (C) 2013 Linaro Ltd <ard.biesheuvel@linaro.org>
-- *
-  * This program is free software; you can redistribute it and/or modify
-  * it under the terms of the GNU General Public License version 2 as
-  * published by the Free Software Foundation.
-@@ -19,76 +17,134 @@
- #include "key.h"
- #include "aes_ccm.h"
--void ieee80211_aes_ccm_encrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad,
--                             u8 *data, size_t data_len, u8 *mic)
-+static void aes_ccm_prepare(struct crypto_cipher *tfm, u8 *scratch, u8 *a)
-+{
-+      int i;
-+      u8 *b_0, *aad, *b, *s_0;
-+
-+      b_0 = scratch + 3 * AES_BLOCK_SIZE;
-+      aad = scratch + 4 * AES_BLOCK_SIZE;
-+      b = scratch;
-+      s_0 = scratch + AES_BLOCK_SIZE;
-+
-+      crypto_cipher_encrypt_one(tfm, b, b_0);
-+
-+      /* Extra Authenticate-only data (always two AES blocks) */
-+      for (i = 0; i < AES_BLOCK_SIZE; i++)
-+              aad[i] ^= b[i];
-+      crypto_cipher_encrypt_one(tfm, b, aad);
-+
-+      aad += AES_BLOCK_SIZE;
-+
-+      for (i = 0; i < AES_BLOCK_SIZE; i++)
-+              aad[i] ^= b[i];
-+      crypto_cipher_encrypt_one(tfm, a, aad);
-+
-+      /* Mask out bits from auth-only-b_0 */
-+      b_0[0] &= 0x07;
-+
-+      /* S_0 is used to encrypt T (= MIC) */
-+      b_0[14] = 0;
-+      b_0[15] = 0;
-+      crypto_cipher_encrypt_one(tfm, s_0, b_0);
-+}
-+
-+
-+void ieee80211_aes_ccm_encrypt(struct crypto_cipher *tfm, u8 *scratch,
-+                             u8 *data, size_t data_len,
-+                             u8 *cdata, u8 *mic)
- {
--      struct scatterlist assoc, pt, ct[2];
-+      int i, j, last_len, num_blocks;
-+      u8 *pos, *cpos, *b, *s_0, *e, *b_0;
--      char aead_req_data[sizeof(struct aead_request) +
--                         crypto_aead_reqsize(tfm)]
--              __aligned(__alignof__(struct aead_request));
--      struct aead_request *aead_req = (void *) aead_req_data;
--
--      memset(aead_req, 0, sizeof(aead_req_data));
--
--      sg_init_one(&pt, data, data_len);
--      sg_init_one(&assoc, &aad[2], be16_to_cpup((__be16 *)aad));
--      sg_init_table(ct, 2);
--      sg_set_buf(&ct[0], data, data_len);
--      sg_set_buf(&ct[1], mic, IEEE80211_CCMP_MIC_LEN);
--
--      aead_request_set_tfm(aead_req, tfm);
--      aead_request_set_assoc(aead_req, &assoc, assoc.length);
--      aead_request_set_crypt(aead_req, &pt, ct, data_len, b_0);
-+      b = scratch;
-+      s_0 = scratch + AES_BLOCK_SIZE;
-+      e = scratch + 2 * AES_BLOCK_SIZE;
-+      b_0 = scratch + 3 * AES_BLOCK_SIZE;
-+
-+      num_blocks = DIV_ROUND_UP(data_len, AES_BLOCK_SIZE);
-+      last_len = data_len % AES_BLOCK_SIZE;
-+      aes_ccm_prepare(tfm, scratch, b);
-+
-+      /* Process payload blocks */
-+      pos = data;
-+      cpos = cdata;
-+      for (j = 1; j <= num_blocks; j++) {
-+              int blen = (j == num_blocks && last_len) ?
-+                      last_len : AES_BLOCK_SIZE;
-+
-+              /* Authentication followed by encryption */
-+              for (i = 0; i < blen; i++)
-+                      b[i] ^= pos[i];
-+              crypto_cipher_encrypt_one(tfm, b, b);
-+
-+              b_0[14] = (j >> 8) & 0xff;
-+              b_0[15] = j & 0xff;
-+              crypto_cipher_encrypt_one(tfm, e, b_0);
-+              for (i = 0; i < blen; i++)
-+                      *cpos++ = *pos++ ^ e[i];
-+      }
--      crypto_aead_encrypt(aead_req);
-+      for (i = 0; i < IEEE80211_CCMP_MIC_LEN; i++)
-+              mic[i] = b[i] ^ s_0[i];
- }
--int ieee80211_aes_ccm_decrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad,
--                            u8 *data, size_t data_len, u8 *mic)
-+
-+int ieee80211_aes_ccm_decrypt(struct crypto_cipher *tfm, u8 *scratch,
-+                            u8 *cdata, size_t data_len, u8 *mic, u8 *data)
- {
--      struct scatterlist assoc, pt, ct[2];
--      char aead_req_data[sizeof(struct aead_request) +
--                         crypto_aead_reqsize(tfm)]
--              __aligned(__alignof__(struct aead_request));
--      struct aead_request *aead_req = (void *) aead_req_data;
--
--      memset(aead_req, 0, sizeof(aead_req_data));
--
--      sg_init_one(&pt, data, data_len);
--      sg_init_one(&assoc, &aad[2], be16_to_cpup((__be16 *)aad));
--      sg_init_table(ct, 2);
--      sg_set_buf(&ct[0], data, data_len);
--      sg_set_buf(&ct[1], mic, IEEE80211_CCMP_MIC_LEN);
--
--      aead_request_set_tfm(aead_req, tfm);
--      aead_request_set_assoc(aead_req, &assoc, assoc.length);
--      aead_request_set_crypt(aead_req, ct, &pt,
--                             data_len + IEEE80211_CCMP_MIC_LEN, b_0);
-+      int i, j, last_len, num_blocks;
-+      u8 *pos, *cpos, *b, *s_0, *a, *b_0;
-+
-+      b = scratch;
-+      s_0 = scratch + AES_BLOCK_SIZE;
-+      a = scratch + 2 * AES_BLOCK_SIZE;
-+      b_0 = scratch + 3 * AES_BLOCK_SIZE;
-+
-+      num_blocks = DIV_ROUND_UP(data_len, AES_BLOCK_SIZE);
-+      last_len = data_len % AES_BLOCK_SIZE;
-+      aes_ccm_prepare(tfm, scratch, a);
-+
-+      /* Process payload blocks */
-+      cpos = cdata;
-+      pos = data;
-+      for (j = 1; j <= num_blocks; j++) {
-+              int blen = (j == num_blocks && last_len) ?
-+                      last_len : AES_BLOCK_SIZE;
-+
-+              /* Decryption followed by authentication */
-+              b_0[14] = (j >> 8) & 0xff;
-+              b_0[15] = j & 0xff;
-+              crypto_cipher_encrypt_one(tfm, b, b_0);
-+              for (i = 0; i < blen; i++) {
-+                      *pos = *cpos++ ^ b[i];
-+                      a[i] ^= *pos++;
-+              }
-+              crypto_cipher_encrypt_one(tfm, a, a);
-+      }
-+
-+      for (i = 0; i < IEEE80211_CCMP_MIC_LEN; i++) {
-+              if ((mic[i] ^ s_0[i]) != a[i])
-+                      return -1;
-+      }
--      return crypto_aead_decrypt(aead_req);
-+      return 0;
- }
--struct crypto_aead *ieee80211_aes_key_setup_encrypt(const u8 key[])
-+
-+struct crypto_cipher *ieee80211_aes_key_setup_encrypt(const u8 key[])
- {
--      struct crypto_aead *tfm;
--      int err;
-+      struct crypto_cipher *tfm;
--      tfm = crypto_alloc_aead("ccm(aes)", 0, CRYPTO_ALG_ASYNC);
--      if (IS_ERR(tfm))
--              return tfm;
--
--      err = crypto_aead_setkey(tfm, key, WLAN_KEY_LEN_CCMP);
--      if (!err)
--              err = crypto_aead_setauthsize(tfm, IEEE80211_CCMP_MIC_LEN);
--      if (!err)
--              return tfm;
-+      tfm = crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC);
-+      if (!IS_ERR(tfm))
-+              crypto_cipher_setkey(tfm, key, WLAN_KEY_LEN_CCMP);
--      crypto_free_aead(tfm);
--      return ERR_PTR(err);
-+      return tfm;
- }
--void ieee80211_aes_key_free(struct crypto_aead *tfm)
-+
-+void ieee80211_aes_key_free(struct crypto_cipher *tfm)
- {
--      crypto_free_aead(tfm);
-+      crypto_free_cipher(tfm);
- }
---- a/net/mac80211/aes_ccm.h
-+++ b/net/mac80211/aes_ccm.h
-@@ -12,11 +12,13 @@
- #include <linux/crypto.h>
--struct crypto_aead *ieee80211_aes_key_setup_encrypt(const u8 key[]);
--void ieee80211_aes_ccm_encrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad,
--                             u8 *data, size_t data_len, u8 *mic);
--int ieee80211_aes_ccm_decrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad,
--                            u8 *data, size_t data_len, u8 *mic);
--void ieee80211_aes_key_free(struct crypto_aead *tfm);
-+struct crypto_cipher *ieee80211_aes_key_setup_encrypt(const u8 key[]);
-+void ieee80211_aes_ccm_encrypt(struct crypto_cipher *tfm, u8 *scratch,
-+                             u8 *data, size_t data_len,
-+                             u8 *cdata, u8 *mic);
-+int ieee80211_aes_ccm_decrypt(struct crypto_cipher *tfm, u8 *scratch,
-+                            u8 *cdata, size_t data_len,
-+                            u8 *mic, u8 *data);
-+void ieee80211_aes_key_free(struct crypto_cipher *tfm);
- #endif /* AES_CCM_H */
---- a/net/mac80211/key.h
-+++ b/net/mac80211/key.h
-@@ -84,7 +84,7 @@ struct ieee80211_key {
-                        * Management frames.
-                        */
-                       u8 rx_pn[IEEE80211_NUM_TIDS + 1][IEEE80211_CCMP_PN_LEN];
--                      struct crypto_aead *tfm;
-+                      struct crypto_cipher *tfm;
-                       u32 replays; /* dot11RSNAStatsCCMPReplays */
-               } ccmp;
-               struct {
---- a/net/mac80211/wpa.c
-+++ b/net/mac80211/wpa.c
-@@ -302,15 +302,22 @@ ieee80211_crypto_tkip_decrypt(struct iee
- }
--static void ccmp_special_blocks(struct sk_buff *skb, u8 *pn, u8 *b_0, u8 *aad)
-+static void ccmp_special_blocks(struct sk_buff *skb, u8 *pn, u8 *scratch,
-+                              int encrypted)
- {
-       __le16 mask_fc;
-       int a4_included, mgmt;
-       u8 qos_tid;
--      u16 len_a;
-+      u8 *b_0, *aad;
-+      u16 data_len, len_a;
-       unsigned int hdrlen;
-       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
-+      memset(scratch, 0, 6 * AES_BLOCK_SIZE);
-+
-+      b_0 = scratch + 3 * AES_BLOCK_SIZE;
-+      aad = scratch + 4 * AES_BLOCK_SIZE;
-+
-       /*
-        * Mask FC: zero subtype b4 b5 b6 (if not mgmt)
-        * Retry, PwrMgt, MoreData; set Protected
-@@ -332,21 +339,20 @@ static void ccmp_special_blocks(struct s
-       else
-               qos_tid = 0;
--      /* In CCM, the initial vectors (IV) used for CTR mode encryption and CBC
--       * mode authentication are not allowed to collide, yet both are derived
--       * from this vector b_0. We only set L := 1 here to indicate that the
--       * data size can be represented in (L+1) bytes. The CCM layer will take
--       * care of storing the data length in the top (L+1) bytes and setting
--       * and clearing the other bits as is required to derive the two IVs.
--       */
--      b_0[0] = 0x1;
-+      data_len = skb->len - hdrlen - IEEE80211_CCMP_HDR_LEN;
-+      if (encrypted)
-+              data_len -= IEEE80211_CCMP_MIC_LEN;
-+      /* First block, b_0 */
-+      b_0[0] = 0x59; /* flags: Adata: 1, M: 011, L: 001 */
-       /* Nonce: Nonce Flags | A2 | PN
-        * Nonce Flags: Priority (b0..b3) | Management (b4) | Reserved (b5..b7)
-        */
-       b_0[1] = qos_tid | (mgmt << 4);
-       memcpy(&b_0[2], hdr->addr2, ETH_ALEN);
-       memcpy(&b_0[8], pn, IEEE80211_CCMP_PN_LEN);
-+      /* l(m) */
-+      put_unaligned_be16(data_len, &b_0[14]);
-       /* AAD (extra authenticate-only data) / masked 802.11 header
-        * FC | A1 | A2 | A3 | SC | [A4] | [QC] */
-@@ -402,8 +408,7 @@ static int ccmp_encrypt_skb(struct ieee8
-       u8 *pos;
-       u8 pn[6];
-       u64 pn64;
--      u8 aad[2 * AES_BLOCK_SIZE];
--      u8 b_0[AES_BLOCK_SIZE];
-+      u8 scratch[6 * AES_BLOCK_SIZE];
-       if (info->control.hw_key &&
-           !(info->control.hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_IV) &&
-@@ -457,9 +462,9 @@ static int ccmp_encrypt_skb(struct ieee8
-               return 0;
-       pos += IEEE80211_CCMP_HDR_LEN;
--      ccmp_special_blocks(skb, pn, b_0, aad);
--      ieee80211_aes_ccm_encrypt(key->u.ccmp.tfm, b_0, aad, pos, len,
--                                skb_put(skb, IEEE80211_CCMP_MIC_LEN));
-+      ccmp_special_blocks(skb, pn, scratch, 0);
-+      ieee80211_aes_ccm_encrypt(key->u.ccmp.tfm, scratch, pos, len,
-+                                pos, skb_put(skb, IEEE80211_CCMP_MIC_LEN));
-       return 0;
- }
-@@ -522,16 +527,16 @@ ieee80211_crypto_ccmp_decrypt(struct iee
-       }
-       if (!(status->flag & RX_FLAG_DECRYPTED)) {
--              u8 aad[2 * AES_BLOCK_SIZE];
--              u8 b_0[AES_BLOCK_SIZE];
-+              u8 scratch[6 * AES_BLOCK_SIZE];
-               /* hardware didn't decrypt/verify MIC */
--              ccmp_special_blocks(skb, pn, b_0, aad);
-+              ccmp_special_blocks(skb, pn, scratch, 1);
-               if (ieee80211_aes_ccm_decrypt(
--                          key->u.ccmp.tfm, b_0, aad,
-+                          key->u.ccmp.tfm, scratch,
-                           skb->data + hdrlen + IEEE80211_CCMP_HDR_LEN,
-                           data_len,
--                          skb->data + skb->len - IEEE80211_CCMP_MIC_LEN))
-+                          skb->data + skb->len - IEEE80211_CCMP_MIC_LEN,
-+                          skb->data + hdrlen + IEEE80211_CCMP_HDR_LEN))
-                       return RX_DROP_UNUSABLE;
-       }
index 92687f0..41a3c4f 100644 (file)
@@ -2,7 +2,7 @@ Used for AP+STA support in OpenWrt - preserve AP mode keys across STA reconnects
 
 --- a/net/mac80211/cfg.c
 +++ b/net/mac80211/cfg.c
-@@ -848,7 +848,6 @@ static int ieee80211_stop_ap(struct wiph
+@@ -856,7 +856,6 @@ static int ieee80211_stop_ap(struct wiph
        sdata->u.ap.driver_smps_mode = IEEE80211_SMPS_OFF;
  
        __sta_info_flush(sdata, true);
index 479b409..de79bd2 100644 (file)
@@ -9,7 +9,7 @@
  static int ieee80211_ifa_changed(struct notifier_block *nb,
                                 unsigned long data, void *arg)
  {
-@@ -346,7 +346,7 @@ static int ieee80211_ifa_changed(struct 
+@@ -346,7 +346,7 @@ static int ieee80211_ifa_changed(struct
  }
  #endif
  
@@ -18,9 +18,9 @@
  static int ieee80211_ifa6_changed(struct notifier_block *nb,
                                  unsigned long data, void *arg)
  {
-@@ -1044,14 +1044,14 @@ int ieee80211_register_hw(struct ieee802
+@@ -1057,14 +1057,14 @@ int ieee80211_register_hw(struct ieee802
+       if (result)
                goto fail_pm_qos;
-       }
  
 -#ifdef CONFIG_INET
 +#ifdef __disabled__CONFIG_INET
@@ -35,7 +35,7 @@
        local->ifa6_notifier.notifier_call = ieee80211_ifa6_changed;
        result = register_inet6addr_notifier(&local->ifa6_notifier);
        if (result)
-@@ -1060,13 +1060,13 @@ int ieee80211_register_hw(struct ieee802
+@@ -1073,13 +1073,13 @@ int ieee80211_register_hw(struct ieee802
  
        return 0;
  
@@ -52,7 +52,7 @@
   fail_ifa:
        pm_qos_remove_notifier(PM_QOS_NETWORK_LATENCY,
                               &local->network_latency_notifier);
-@@ -1111,10 +1111,10 @@ void ieee80211_unregister_hw(struct ieee
+@@ -1124,10 +1124,10 @@ void ieee80211_unregister_hw(struct ieee
  
        pm_qos_remove_notifier(PM_QOS_NETWORK_LATENCY,
                               &local->network_latency_notifier);
index 9e94d00..47dcec3 100644 (file)
@@ -1,6 +1,6 @@
 --- a/net/mac80211/cfg.c
 +++ b/net/mac80211/cfg.c
-@@ -1947,7 +1947,7 @@ static int ieee80211_scan(struct wiphy *
+@@ -1963,7 +1963,7 @@ static int ieee80211_scan(struct wiphy *
                 * the  frames sent while scanning on other channel will be
                 * lost)
                 */
diff --git a/package/kernel/mac80211/patches/300-Revert-ath5k-Remove-AHB-bus-support.patch b/package/kernel/mac80211/patches/300-Revert-ath5k-Remove-AHB-bus-support.patch
deleted file mode 100644 (file)
index cb71499..0000000
+++ /dev/null
@@ -1,395 +0,0 @@
-From: Felix Fietkau <nbd@openwrt.org>
-Date: Sat, 27 Sep 2014 15:57:09 +0200
-Subject: [PATCH] Revert "ath5k: Remove AHB bus support"
-
-This reverts commit 093ec3c5337434f40d77c1af06c139da3e5ba6dc.
----
- create mode 100644 drivers/net/wireless/ath/ath5k/ahb.c
-
---- a/drivers/net/wireless/ath/ath5k/Kconfig
-+++ b/drivers/net/wireless/ath/ath5k/Kconfig
-@@ -1,13 +1,14 @@
- config ATH5K
-       tristate "Atheros 5xxx wireless cards support"
-       depends on m
--      depends on PCI && MAC80211
-+      depends on (PCI || ATHEROS_AR231X) && MAC80211
-       select ATH_COMMON
-       select MAC80211_LEDS
-       select BACKPORT_LEDS_CLASS
-       select BACKPORT_NEW_LEDS
-       select BACKPORT_AVERAGE
--      select ATH5K_PCI
-+      select ATH5K_AHB if (ATHEROS_AR231X && !PCI)
-+      select ATH5K_PCI if (!ATHEROS_AR231X && PCI)
-       ---help---
-         This module adds support for wireless adapters based on
-         Atheros 5xxx chipset.
-@@ -52,9 +53,16 @@ config ATH5K_TRACER
-         If unsure, say N.
-+config ATH5K_AHB
-+      bool "Atheros 5xxx AHB bus support"
-+      depends on (ATHEROS_AR231X && !PCI)
-+      ---help---
-+        This adds support for WiSoC type chipsets of the 5xxx Atheros
-+        family.
-+
- config ATH5K_PCI
-       bool "Atheros 5xxx PCI bus support"
--      depends on PCI
-+      depends on (!ATHEROS_AR231X && PCI)
-       ---help---
-         This adds support for PCI type chipsets of the 5xxx Atheros
-         family.
---- a/drivers/net/wireless/ath/ath5k/Makefile
-+++ b/drivers/net/wireless/ath/ath5k/Makefile
-@@ -17,5 +17,6 @@ ath5k-y                              += ani.o
- ath5k-y                               += sysfs.o
- ath5k-y                               += mac80211-ops.o
- ath5k-$(CPTCFG_ATH5K_DEBUG)   += debug.o
-+ath5k-$(CPTCFG_ATH5K_AHB)     += ahb.o
- ath5k-$(CPTCFG_ATH5K_PCI)     += pci.o
- obj-$(CPTCFG_ATH5K)           += ath5k.o
---- /dev/null
-+++ b/drivers/net/wireless/ath/ath5k/ahb.c
-@@ -0,0 +1,234 @@
-+/*
-+ * Copyright (c) 2008-2009 Atheros Communications Inc.
-+ * Copyright (c) 2009 Gabor Juhos <juhosg@openwrt.org>
-+ * Copyright (c) 2009 Imre Kaloz <kaloz@openwrt.org>
-+ *
-+ * Permission to use, copy, modify, and/or distribute this software for any
-+ * purpose with or without fee is hereby granted, provided that the above
-+ * copyright notice and this permission notice appear in all copies.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+ */
-+
-+#include <linux/nl80211.h>
-+#include <linux/platform_device.h>
-+#include <linux/etherdevice.h>
-+#include <linux/export.h>
-+#include <ar231x_platform.h>
-+#include "ath5k.h"
-+#include "debug.h"
-+#include "base.h"
-+#include "reg.h"
-+
-+/* return bus cachesize in 4B word units */
-+static void ath5k_ahb_read_cachesize(struct ath_common *common, int *csz)
-+{
-+      *csz = L1_CACHE_BYTES >> 2;
-+}
-+
-+static bool
-+ath5k_ahb_eeprom_read(struct ath_common *common, u32 off, u16 *data)
-+{
-+      struct ath5k_hw *ah = common->priv;
-+      struct platform_device *pdev = to_platform_device(ah->dev);
-+      struct ar231x_board_config *bcfg = dev_get_platdata(&pdev->dev);
-+      u16 *eeprom, *eeprom_end;
-+
-+      eeprom = (u16 *) bcfg->radio;
-+      eeprom_end = ((void *) bcfg->config) + BOARD_CONFIG_BUFSZ;
-+
-+      eeprom += off;
-+      if (eeprom > eeprom_end)
-+              return false;
-+
-+      *data = *eeprom;
-+      return true;
-+}
-+
-+int ath5k_hw_read_srev(struct ath5k_hw *ah)
-+{
-+      struct platform_device *pdev = to_platform_device(ah->dev);
-+      struct ar231x_board_config *bcfg = dev_get_platdata(&pdev->dev);
-+      ah->ah_mac_srev = bcfg->devid;
-+      return 0;
-+}
-+
-+static int ath5k_ahb_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac)
-+{
-+      struct platform_device *pdev = to_platform_device(ah->dev);
-+      struct ar231x_board_config *bcfg = dev_get_platdata(&pdev->dev);
-+      u8 *cfg_mac;
-+
-+      if (to_platform_device(ah->dev)->id == 0)
-+              cfg_mac = bcfg->config->wlan0_mac;
-+      else
-+              cfg_mac = bcfg->config->wlan1_mac;
-+
-+      memcpy(mac, cfg_mac, ETH_ALEN);
-+      return 0;
-+}
-+
-+static const struct ath_bus_ops ath_ahb_bus_ops = {
-+      .ath_bus_type = ATH_AHB,
-+      .read_cachesize = ath5k_ahb_read_cachesize,
-+      .eeprom_read = ath5k_ahb_eeprom_read,
-+      .eeprom_read_mac = ath5k_ahb_eeprom_read_mac,
-+};
-+
-+/*Initialization*/
-+static int ath_ahb_probe(struct platform_device *pdev)
-+{
-+      struct ar231x_board_config *bcfg = dev_get_platdata(&pdev->dev);
-+      struct ath5k_hw *ah;
-+      struct ieee80211_hw *hw;
-+      struct resource *res;
-+      void __iomem *mem;
-+      int irq;
-+      int ret = 0;
-+      u32 reg;
-+
-+      if (!dev_get_platdata(&pdev->dev)) {
-+              dev_err(&pdev->dev, "no platform data specified\n");
-+              ret = -EINVAL;
-+              goto err_out;
-+      }
-+
-+      res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-+      if (res == NULL) {
-+              dev_err(&pdev->dev, "no memory resource found\n");
-+              ret = -ENXIO;
-+              goto err_out;
-+      }
-+
-+      mem = ioremap_nocache(res->start, resource_size(res));
-+      if (mem == NULL) {
-+              dev_err(&pdev->dev, "ioremap failed\n");
-+              ret = -ENOMEM;
-+              goto err_out;
-+      }
-+
-+      res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-+      if (res == NULL) {
-+              dev_err(&pdev->dev, "no IRQ resource found\n");
-+              ret = -ENXIO;
-+              goto err_iounmap;
-+      }
-+
-+      irq = res->start;
-+
-+      hw = ieee80211_alloc_hw(sizeof(struct ath5k_hw), &ath5k_hw_ops);
-+      if (hw == NULL) {
-+              dev_err(&pdev->dev, "no memory for ieee80211_hw\n");
-+              ret = -ENOMEM;
-+              goto err_iounmap;
-+      }
-+
-+      ah = hw->priv;
-+      ah->hw = hw;
-+      ah->dev = &pdev->dev;
-+      ah->iobase = mem;
-+      ah->irq = irq;
-+      ah->devid = bcfg->devid;
-+
-+      if (bcfg->devid >= AR5K_SREV_AR2315_R6) {
-+              /* Enable WMAC AHB arbitration */
-+              reg = ioread32((void __iomem *) AR5K_AR2315_AHB_ARB_CTL);
-+              reg |= AR5K_AR2315_AHB_ARB_CTL_WLAN;
-+              iowrite32(reg, (void __iomem *) AR5K_AR2315_AHB_ARB_CTL);
-+
-+              /* Enable global WMAC swapping */
-+              reg = ioread32((void __iomem *) AR5K_AR2315_BYTESWAP);
-+              reg |= AR5K_AR2315_BYTESWAP_WMAC;
-+              iowrite32(reg, (void __iomem *) AR5K_AR2315_BYTESWAP);
-+      } else {
-+              /* Enable WMAC DMA access (assuming 5312 or 231x*/
-+              /* TODO: check other platforms */
-+              reg = ioread32((void __iomem *) AR5K_AR5312_ENABLE);
-+              if (to_platform_device(ah->dev)->id == 0)
-+                      reg |= AR5K_AR5312_ENABLE_WLAN0;
-+              else
-+                      reg |= AR5K_AR5312_ENABLE_WLAN1;
-+              iowrite32(reg, (void __iomem *) AR5K_AR5312_ENABLE);
-+
-+              /*
-+               * On a dual-band AR5312, the multiband radio is only
-+               * used as pass-through. Disable 2 GHz support in the
-+               * driver for it
-+               */
-+              if (to_platform_device(ah->dev)->id == 0 &&
-+                  (bcfg->config->flags & (BD_WLAN0 | BD_WLAN1)) ==
-+                   (BD_WLAN1 | BD_WLAN0))
-+                      ah->ah_capabilities.cap_needs_2GHz_ovr = true;
-+              else
-+                      ah->ah_capabilities.cap_needs_2GHz_ovr = false;
-+      }
-+
-+      ret = ath5k_init_ah(ah, &ath_ahb_bus_ops);
-+      if (ret != 0) {
-+              dev_err(&pdev->dev, "failed to attach device, err=%d\n", ret);
-+              ret = -ENODEV;
-+              goto err_free_hw;
-+      }
-+
-+      platform_set_drvdata(pdev, hw);
-+
-+      return 0;
-+
-+ err_free_hw:
-+      ieee80211_free_hw(hw);
-+ err_iounmap:
-+        iounmap(mem);
-+ err_out:
-+      return ret;
-+}
-+
-+static int ath_ahb_remove(struct platform_device *pdev)
-+{
-+      struct ar231x_board_config *bcfg = dev_get_platdata(&pdev->dev);
-+      struct ieee80211_hw *hw = platform_get_drvdata(pdev);
-+      struct ath5k_hw *ah;
-+      u32 reg;
-+
-+      if (!hw)
-+              return 0;
-+
-+      ah = hw->priv;
-+
-+      if (bcfg->devid >= AR5K_SREV_AR2315_R6) {
-+              /* Disable WMAC AHB arbitration */
-+              reg = ioread32((void __iomem *) AR5K_AR2315_AHB_ARB_CTL);
-+              reg &= ~AR5K_AR2315_AHB_ARB_CTL_WLAN;
-+              iowrite32(reg, (void __iomem *) AR5K_AR2315_AHB_ARB_CTL);
-+      } else {
-+              /*Stop DMA access */
-+              reg = ioread32((void __iomem *) AR5K_AR5312_ENABLE);
-+              if (to_platform_device(ah->dev)->id == 0)
-+                      reg &= ~AR5K_AR5312_ENABLE_WLAN0;
-+              else
-+                      reg &= ~AR5K_AR5312_ENABLE_WLAN1;
-+              iowrite32(reg, (void __iomem *) AR5K_AR5312_ENABLE);
-+      }
-+
-+      ath5k_deinit_ah(ah);
-+      iounmap(ah->iobase);
-+      ieee80211_free_hw(hw);
-+
-+      return 0;
-+}
-+
-+static struct platform_driver ath_ahb_driver = {
-+      .probe      = ath_ahb_probe,
-+      .remove     = ath_ahb_remove,
-+      .driver         = {
-+              .name   = "ar231x-wmac",
-+              .owner  = THIS_MODULE,
-+      },
-+};
-+
-+module_platform_driver(ath_ahb_driver);
---- a/drivers/net/wireless/ath/ath5k/ath5k.h
-+++ b/drivers/net/wireless/ath/ath5k/ath5k.h
-@@ -1647,6 +1647,32 @@ static inline struct ath_regulatory *ath
-       return &(ath5k_hw_common(ah)->regulatory);
- }
-+#ifdef CONFIG_ATHEROS_AR231X
-+#define AR5K_AR2315_PCI_BASE  ((void __iomem *)0xb0100000)
-+
-+static inline void __iomem *ath5k_ahb_reg(struct ath5k_hw *ah, u16 reg)
-+{
-+      /* On AR2315 and AR2317 the PCI clock domain registers
-+       * are outside of the WMAC register space */
-+      if (unlikely((reg >= 0x4000) && (reg < 0x5000) &&
-+          (ah->ah_mac_srev >= AR5K_SREV_AR2315_R6)))
-+              return AR5K_AR2315_PCI_BASE + reg;
-+
-+      return ah->iobase + reg;
-+}
-+
-+static inline u32 ath5k_hw_reg_read(struct ath5k_hw *ah, u16 reg)
-+{
-+      return ioread32(ath5k_ahb_reg(ah, reg));
-+}
-+
-+static inline void ath5k_hw_reg_write(struct ath5k_hw *ah, u32 val, u16 reg)
-+{
-+      iowrite32(val, ath5k_ahb_reg(ah, reg));
-+}
-+
-+#else
-+
- static inline u32 ath5k_hw_reg_read(struct ath5k_hw *ah, u16 reg)
- {
-       return ioread32(ah->iobase + reg);
-@@ -1657,6 +1683,8 @@ static inline void ath5k_hw_reg_write(st
-       iowrite32(val, ah->iobase + reg);
- }
-+#endif
-+
- static inline enum ath_bus_type ath5k_get_bus_type(struct ath5k_hw *ah)
- {
-       return ath5k_hw_common(ah)->bus_ops->ath_bus_type;
---- a/drivers/net/wireless/ath/ath5k/base.c
-+++ b/drivers/net/wireless/ath/ath5k/base.c
-@@ -99,6 +99,15 @@ static int ath5k_reset(struct ath5k_hw *
- /* Known SREVs */
- static const struct ath5k_srev_name srev_names[] = {
-+#ifdef CONFIG_ATHEROS_AR231X
-+      { "5312",       AR5K_VERSION_MAC,       AR5K_SREV_AR5312_R2 },
-+      { "5312",       AR5K_VERSION_MAC,       AR5K_SREV_AR5312_R7 },
-+      { "2313",       AR5K_VERSION_MAC,       AR5K_SREV_AR2313_R8 },
-+      { "2315",       AR5K_VERSION_MAC,       AR5K_SREV_AR2315_R6 },
-+      { "2315",       AR5K_VERSION_MAC,       AR5K_SREV_AR2315_R7 },
-+      { "2317",       AR5K_VERSION_MAC,       AR5K_SREV_AR2317_R1 },
-+      { "2317",       AR5K_VERSION_MAC,       AR5K_SREV_AR2317_R2 },
-+#else
-       { "5210",       AR5K_VERSION_MAC,       AR5K_SREV_AR5210 },
-       { "5311",       AR5K_VERSION_MAC,       AR5K_SREV_AR5311 },
-       { "5311A",      AR5K_VERSION_MAC,       AR5K_SREV_AR5311A },
-@@ -117,6 +126,7 @@ static const struct ath5k_srev_name srev
-       { "5418",       AR5K_VERSION_MAC,       AR5K_SREV_AR5418 },
-       { "2425",       AR5K_VERSION_MAC,       AR5K_SREV_AR2425 },
-       { "2417",       AR5K_VERSION_MAC,       AR5K_SREV_AR2417 },
-+#endif
-       { "xxxxx",      AR5K_VERSION_MAC,       AR5K_SREV_UNKNOWN },
-       { "5110",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_5110 },
-       { "5111",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_5111 },
-@@ -132,6 +142,10 @@ static const struct ath5k_srev_name srev
-       { "5413",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_5413 },
-       { "5424",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_5424 },
-       { "5133",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_5133 },
-+#ifdef CONFIG_ATHEROS_AR231X
-+      { "2316",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_2316 },
-+      { "2317",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_2317 },
-+#endif
-       { "xxxxx",      AR5K_VERSION_RAD,       AR5K_SREV_UNKNOWN },
- };
---- a/drivers/net/wireless/ath/ath5k/led.c
-+++ b/drivers/net/wireless/ath/ath5k/led.c
-@@ -163,14 +163,20 @@ int ath5k_init_leds(struct ath5k_hw *ah)
- {
-       int ret = 0;
-       struct ieee80211_hw *hw = ah->hw;
-+#ifndef CONFIG_ATHEROS_AR231X
-       struct pci_dev *pdev = ah->pdev;
-+#endif
-       char name[ATH5K_LED_MAX_NAME_LEN + 1];
-       const struct pci_device_id *match;
-       if (!ah->pdev)
-               return 0;
-+#ifdef CONFIG_ATHEROS_AR231X
-+      match = NULL;
-+#else
-       match = pci_match_id(&ath5k_led_devices[0], pdev);
-+#endif
-       if (match) {
-               __set_bit(ATH_STAT_LEDSOFT, ah->status);
-               ah->led_pin = ATH_PIN(match->driver_data);
diff --git a/package/kernel/mac80211/patches/300-mac80211-add-an-intermediate-software-queue-implemen.patch b/package/kernel/mac80211/patches/300-mac80211-add-an-intermediate-software-queue-implemen.patch
new file mode 100644 (file)
index 0000000..dbf9737
--- /dev/null
@@ -0,0 +1,570 @@
+From: Felix Fietkau <nbd@openwrt.org>
+Date: Tue, 18 Nov 2014 23:58:51 +0100
+Subject: [PATCH] mac80211: add an intermediate software queue implementation
+
+This allows drivers to request per-vif and per-sta-tid queues from which
+they can pull frames. This makes it easier to keep the hardware queues
+short, and to improve fairness between clients and vifs.
+
+The task of scheduling packet transmission is left up to the driver -
+queueing is controlled by mac80211. Drivers can only dequeue packets by
+calling ieee80211_tx_dequeue. This makes it possible to add active queue
+management later without changing drivers using this code.
+
+This can also be used as a starting point to implement A-MSDU
+aggregation in a way that does not add artificially induced latency.
+
+Signed-off-by: Felix Fietkau <nbd@openwrt.org>
+---
+
+--- a/include/net/mac80211.h
++++ b/include/net/mac80211.h
+@@ -1257,6 +1257,8 @@ struct ieee80211_vif {
+       u8 cab_queue;
+       u8 hw_queue[IEEE80211_NUM_ACS];
++      struct ieee80211_txq *txq;
++
+       struct ieee80211_chanctx_conf __rcu *chanctx_conf;
+       u32 driver_flags;
+@@ -1519,6 +1521,8 @@ struct ieee80211_sta {
+       bool tdls_initiator;
+       bool mfp;
++      struct ieee80211_txq *txq[IEEE80211_NUM_TIDS];
++
+       /* must be last */
+       u8 drv_priv[0] __aligned(sizeof(void *));
+ };
+@@ -1547,6 +1551,27 @@ struct ieee80211_tx_control {
+ };
+ /**
++ * struct ieee80211_txq - Software intermediate tx queue
++ *
++ * @vif: &struct ieee80211_vif pointer from the add_interface callback.
++ * @sta: station table entry, may be NULL for per-vif queue
++ * @tid: the TID for this queue (unset for per-vif queue)
++ * @ac: the AC for this queue
++ *
++ * The driver can obtain packets from this queue by calling
++ * ieee80211_tx_dequeue().
++ */
++struct ieee80211_txq {
++      struct ieee80211_vif *vif;
++      struct ieee80211_sta *sta;
++      u8 tid;
++      u8 ac;
++
++      /* must be last */
++      u8 drv_priv[0] __aligned(sizeof(void *));
++};
++
++/**
+  * enum ieee80211_hw_flags - hardware flags
+  *
+  * These flags are used to indicate hardware capabilities to
+@@ -1770,6 +1795,8 @@ enum ieee80211_hw_flags {
+  *    within &struct ieee80211_sta.
+  * @chanctx_data_size: size (in bytes) of the drv_priv data area
+  *    within &struct ieee80211_chanctx_conf.
++ * @txq_data_size: size (in bytes) of the drv_priv data area
++ *    within @struct ieee80211_txq.
+  *
+  * @max_rates: maximum number of alternate rate retry stages the hw
+  *    can handle.
+@@ -1818,6 +1845,9 @@ enum ieee80211_hw_flags {
+  * @n_cipher_schemes: a size of an array of cipher schemes definitions.
+  * @cipher_schemes: a pointer to an array of cipher scheme definitions
+  *    supported by HW.
++ *
++ * @txq_ac_max_pending: maximum number of frames per AC pending in all txq
++ *    entries for a vif.
+  */
+ struct ieee80211_hw {
+       struct ieee80211_conf conf;
+@@ -1830,6 +1860,7 @@ struct ieee80211_hw {
+       int vif_data_size;
+       int sta_data_size;
+       int chanctx_data_size;
++      int txq_data_size;
+       u16 queues;
+       u16 max_listen_interval;
+       s8 max_signal;
+@@ -1846,6 +1877,7 @@ struct ieee80211_hw {
+       u8 uapsd_max_sp_len;
+       u8 n_cipher_schemes;
+       const struct ieee80211_cipher_scheme *cipher_schemes;
++      int txq_ac_max_pending;
+ };
+ /**
+@@ -3007,6 +3039,8 @@ enum ieee80211_reconfig_type {
+  *    response template is provided, together with the location of the
+  *    switch-timing IE within the template. The skb can only be used within
+  *    the function call.
++ *
++ * @wake_tx_queue: Called when new packets have been added to the queue.
+  */
+ struct ieee80211_ops {
+       void (*tx)(struct ieee80211_hw *hw,
+@@ -3238,6 +3272,9 @@ struct ieee80211_ops {
+       void (*tdls_recv_channel_switch)(struct ieee80211_hw *hw,
+                                        struct ieee80211_vif *vif,
+                                        struct ieee80211_tdls_ch_sw_params *params);
++
++      void (*wake_tx_queue)(struct ieee80211_hw *hw,
++                            struct ieee80211_txq *txq);
+ };
+ /**
+@@ -5249,4 +5286,17 @@ void ieee80211_unreserve_tid(struct ieee
+  */
+ size_t ieee80211_ie_split(const u8 *ies, size_t ielen,
+                         const u8 *ids, int n_ids, size_t offset);
++
++/**
++ * ieee80211_tx_dequeue - dequeue a packet from a software tx queue
++ *
++ * @hw: pointer as obtained from ieee80211_alloc_hw()
++ * @txq: pointer obtained from .add_tx_queue() call
++ *
++ * Returns the sjb if successful, ERR_PTR(-EAGAIN) if no frame was available.
++ */
++struct sk_buff *ieee80211_tx_dequeue(struct ieee80211_hw *hw,
++                                   struct ieee80211_txq *txq);
++
++
+ #endif /* MAC80211_H */
+--- a/net/mac80211/driver-ops.h
++++ b/net/mac80211/driver-ops.h
+@@ -1367,4 +1367,21 @@ drv_tdls_recv_channel_switch(struct ieee
+       trace_drv_return_void(local);
+ }
++static inline void drv_wake_tx_queue(struct ieee80211_local *local,
++                                   struct txq_info *txq)
++{
++      struct ieee80211_sub_if_data *sdata = vif_to_sdata(txq->txq.vif);
++
++      if (!check_sdata_in_driver(sdata))
++              return;
++
++      if (txq->txq.sta)
++              trace_drv_wake_sta_tx_queue(local, sdata, txq->txq.sta,
++                                          txq->txq.tid);
++      else
++              trace_drv_wake_vif_tx_queue(local, sdata);
++
++      local->ops->wake_tx_queue(&local->hw, &txq->txq);
++}
++
+ #endif /* __MAC80211_DRIVER_OPS */
+--- a/net/mac80211/ieee80211_i.h
++++ b/net/mac80211/ieee80211_i.h
+@@ -809,6 +809,13 @@ struct mac80211_qos_map {
+       struct rcu_head rcu_head;
+ };
++struct txq_info {
++      struct sk_buff_head queue;
++
++      /* keep last! */
++      struct ieee80211_txq txq;
++};
++
+ struct ieee80211_sub_if_data {
+       struct list_head list;
+@@ -853,6 +860,7 @@ struct ieee80211_sub_if_data {
+       bool control_port_no_encrypt;
+       int encrypt_headroom;
++      atomic_t txqs_len[IEEE80211_NUM_ACS];
+       struct ieee80211_tx_queue_params tx_conf[IEEE80211_NUM_ACS];
+       struct mac80211_qos_map __rcu *qos_map;
+@@ -1905,6 +1913,12 @@ static inline bool ieee80211_can_run_wor
+       return true;
+ }
++void ieee80211_init_tx_queue(struct ieee80211_sub_if_data *sdata,
++                           struct sta_info *sta,
++                           struct txq_info *txq, int tid);
++void ieee80211_flush_tx_queue(struct ieee80211_local *local,
++                            struct ieee80211_txq *txq);
++
+ void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
+                        u16 transaction, u16 auth_alg, u16 status,
+                        const u8 *extra, size_t extra_len, const u8 *bssid,
+--- a/net/mac80211/iface.c
++++ b/net/mac80211/iface.c
+@@ -969,6 +969,9 @@ static void ieee80211_do_stop(struct iee
+       }
+       spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
++      if (sdata->vif.txq)
++              ieee80211_flush_tx_queue(local, sdata->vif.txq);
++
+       if (local->open_count == 0)
+               ieee80211_clear_tx_pending(local);
+@@ -1773,6 +1776,15 @@ int ieee80211_if_add(struct ieee80211_lo
+       ieee80211_setup_sdata(sdata, type);
+       if (ndev) {
++              struct txq_info *txqi = NULL;
++
++              if (local->ops->wake_tx_queue) {
++                      txqi = kzalloc(sizeof(*txqi) +
++                                    local->hw.txq_data_size, GFP_KERNEL);
++                      if (txqi)
++                              ieee80211_init_tx_queue(sdata, NULL, txqi, 0);
++              }
++
+               if (params) {
+                       ndev->ieee80211_ptr->use_4addr = params->use_4addr;
+                       if (type == NL80211_IFTYPE_STATION)
+@@ -1785,6 +1797,7 @@ int ieee80211_if_add(struct ieee80211_lo
+               ret = register_netdevice(ndev);
+               if (ret) {
++                      kfree(txqi);
+                       free_netdev(ndev);
+                       return ret;
+               }
+@@ -1802,6 +1815,7 @@ int ieee80211_if_add(struct ieee80211_lo
+ void ieee80211_if_remove(struct ieee80211_sub_if_data *sdata)
+ {
++      struct txq_info *txqi;
+       ASSERT_RTNL();
+       mutex_lock(&sdata->local->iflist_mtx);
+@@ -1810,6 +1824,11 @@ void ieee80211_if_remove(struct ieee8021
+       synchronize_rcu();
++      if (sdata->vif.txq) {
++              txqi = container_of(sdata->vif.txq, struct txq_info, txq);
++              kfree(txqi);
++      }
++
+       if (sdata->dev) {
+               unregister_netdevice(sdata->dev);
+       } else {
+@@ -1833,6 +1852,7 @@ void ieee80211_sdata_stop(struct ieee802
+ void ieee80211_remove_interfaces(struct ieee80211_local *local)
+ {
+       struct ieee80211_sub_if_data *sdata, *tmp;
++      struct txq_info *txqi;
+       LIST_HEAD(unreg_list);
+       LIST_HEAD(wdev_list);
+@@ -1851,6 +1871,12 @@ void ieee80211_remove_interfaces(struct 
+       list_for_each_entry_safe(sdata, tmp, &local->interfaces, list) {
+               list_del(&sdata->list);
++              if (sdata->vif.txq) {
++                      txqi = container_of(sdata->vif.txq, struct txq_info,
++                                         txq);
++                      kfree(txqi);
++              }
++
+               if (sdata->dev)
+                       unregister_netdevice_queue(sdata->dev, &unreg_list);
+               else
+--- a/net/mac80211/main.c
++++ b/net/mac80211/main.c
+@@ -1019,6 +1019,9 @@ int ieee80211_register_hw(struct ieee802
+       local->dynamic_ps_forced_timeout = -1;
++      if (!local->hw.txq_ac_max_pending)
++              local->hw.txq_ac_max_pending = 64;
++
+       result = ieee80211_wep_init(local);
+       if (result < 0)
+               wiphy_debug(local->hw.wiphy, "Failed to initialize wep: %d\n",
+--- a/net/mac80211/sta_info.c
++++ b/net/mac80211/sta_info.c
+@@ -118,6 +118,11 @@ static void __cleanup_single_sta(struct 
+               atomic_dec(&ps->num_sta_ps);
+       }
++      if (sta->txq) {
++              for (i = 0; i < IEEE80211_NUM_TIDS; i++)
++                      ieee80211_flush_tx_queue(local, sta->sta.txq[i]);
++      }
++
+       for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
+               local->total_ps_buffered -= skb_queue_len(&sta->ps_tx_buf[ac]);
+               ieee80211_purge_tx_queue(&local->hw, &sta->ps_tx_buf[ac]);
+@@ -234,6 +239,7 @@ void sta_info_free(struct ieee80211_loca
+       sta_dbg(sta->sdata, "Destroyed STA %pM\n", sta->sta.addr);
++      kfree(sta->txq);
+       kfree(rcu_dereference_raw(sta->sta.rates));
+       kfree(sta);
+ }
+@@ -285,11 +291,12 @@ struct sta_info *sta_info_alloc(struct i
+                               const u8 *addr, gfp_t gfp)
+ {
+       struct ieee80211_local *local = sdata->local;
++      struct ieee80211_hw *hw = &local->hw;
+       struct sta_info *sta;
+       struct timespec uptime;
+       int i;
+-      sta = kzalloc(sizeof(*sta) + local->hw.sta_data_size, gfp);
++      sta = kzalloc(sizeof(*sta) + hw->sta_data_size, gfp);
+       if (!sta)
+               return NULL;
+@@ -321,11 +328,23 @@ struct sta_info *sta_info_alloc(struct i
+       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);
+-              return NULL;
++      if (local->ops->wake_tx_queue) {
++              int size = sizeof(struct txq_info) +
++                         ALIGN(hw->txq_data_size, sizeof(void *));
++
++              sta->txq = kcalloc(IEEE80211_NUM_TIDS, size, gfp);
++              if (!sta->txq)
++                      goto free;
++
++              for (i = 0; i < IEEE80211_NUM_TIDS; i++) {
++                      struct txq_info *txq = sta->txq + i * size;
++                      ieee80211_init_tx_queue(sdata, sta, txq, i);
++              }
+       }
++      if (sta_prepare_rate_control(local, sta, gfp))
++              goto free_txq;
++
+       for (i = 0; i < IEEE80211_NUM_TIDS; i++) {
+               /*
+                * timer_to_tid must be initialized with identity mapping
+@@ -346,7 +365,7 @@ struct sta_info *sta_info_alloc(struct i
+       if (sdata->vif.type == NL80211_IFTYPE_AP ||
+           sdata->vif.type == NL80211_IFTYPE_AP_VLAN) {
+               struct ieee80211_supported_band *sband =
+-                      local->hw.wiphy->bands[ieee80211_get_sdata_band(sdata)];
++                      hw->wiphy->bands[ieee80211_get_sdata_band(sdata)];
+               u8 smps = (sband->ht_cap.cap & IEEE80211_HT_CAP_SM_PS) >>
+                               IEEE80211_HT_CAP_SM_PS_SHIFT;
+               /*
+@@ -371,6 +390,12 @@ struct sta_info *sta_info_alloc(struct i
+       sta_dbg(sdata, "Allocated STA %pM\n", sta->sta.addr);
+       return sta;
++
++free_txq:
++      kfree(sta->txq);
++free:
++      kfree(sta);
++      return NULL;
+ }
+ static int sta_info_insert_check(struct sta_info *sta)
+--- a/net/mac80211/sta_info.h
++++ b/net/mac80211/sta_info.h
+@@ -368,6 +368,7 @@ struct sta_info {
+       struct sk_buff_head ps_tx_buf[IEEE80211_NUM_ACS];
+       struct sk_buff_head tx_filtered[IEEE80211_NUM_ACS];
+       unsigned long driver_buffered_tids;
++      struct txq_info *txq;
+       /* Updated from RX path only, no locking requirements */
+       unsigned long rx_packets;
+--- a/net/mac80211/trace.h
++++ b/net/mac80211/trace.h
+@@ -2312,6 +2312,40 @@ TRACE_EVENT(drv_tdls_recv_channel_switch
+       )
+ );
++DEFINE_EVENT(local_sdata_evt, drv_wake_vif_tx_queue,
++      TP_PROTO(struct ieee80211_local *local,
++               struct ieee80211_sub_if_data *sdata),
++      TP_ARGS(local, sdata)
++);
++
++TRACE_EVENT(drv_wake_sta_tx_queue,
++      TP_PROTO(struct ieee80211_local *local,
++               struct ieee80211_sub_if_data *sdata,
++               struct ieee80211_sta *sta,
++               u8 tid),
++
++      TP_ARGS(local, sdata, sta, tid),
++
++      TP_STRUCT__entry(
++              LOCAL_ENTRY
++              VIF_ENTRY
++              STA_ENTRY
++              __field(u8, tid)
++      ),
++
++      TP_fast_assign(
++              LOCAL_ASSIGN;
++              VIF_ASSIGN;
++              STA_ASSIGN;
++              __entry->tid = tid;
++      ),
++
++      TP_printk(
++              LOCAL_PR_FMT  VIF_PR_FMT  STA_PR_FMT " tid: 0x%x",
++              LOCAL_PR_ARG, VIF_PR_ARG, STA_PR_ARG, __entry->tid
++      )
++);
++
+ #ifdef CPTCFG_MAC80211_MESSAGE_TRACING
+ #undef TRACE_SYSTEM
+ #define TRACE_SYSTEM mac80211_msg
+--- a/net/mac80211/tx.c
++++ b/net/mac80211/tx.c
+@@ -1201,13 +1201,76 @@ ieee80211_tx_prepare(struct ieee80211_su
+       return TX_CONTINUE;
+ }
++static void ieee80211_drv_tx(struct ieee80211_local *local,
++                           struct ieee80211_vif *vif,
++                           struct ieee80211_sta *pubsta,
++                           struct sk_buff *skb)
++{
++      struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
++      struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
++      struct ieee80211_tx_control control = {
++              .sta = pubsta
++      };
++      struct ieee80211_txq *txq = NULL;
++      struct txq_info *txqi;
++      u8 ac;
++
++      if (ieee80211_is_mgmt(hdr->frame_control) ||
++          ieee80211_is_ctl(hdr->frame_control))
++              goto tx_normal;
++
++      if (pubsta) {
++              u8 tid = skb->priority & IEEE80211_QOS_CTL_TID_MASK;
++              txq = pubsta->txq[tid];
++      } else if (vif) {
++              txq = vif->txq;
++      }
++
++      if (!txq)
++              goto tx_normal;
++
++      ac = txq->ac;
++      txqi = container_of(txq, struct txq_info, txq);
++      atomic_inc(&sdata->txqs_len[ac]);
++      if (atomic_read(&sdata->txqs_len[ac]) >= local->hw.txq_ac_max_pending)
++              netif_stop_subqueue(sdata->dev, ac);
++
++      skb_queue_tail(&txqi->queue, skb);
++      drv_wake_tx_queue(local, txqi);
++
++      return;
++
++tx_normal:
++      drv_tx(local, &control, skb);
++}
++
++struct sk_buff *ieee80211_tx_dequeue(struct ieee80211_hw *hw,
++                                   struct ieee80211_txq *txq)
++{
++      struct ieee80211_local *local = hw_to_local(hw);
++      struct ieee80211_sub_if_data *sdata = vif_to_sdata(txq->vif);
++      struct txq_info *txqi = container_of(txq, struct txq_info, txq);
++      struct sk_buff *skb;
++      u8 ac = txq->ac;
++
++      skb = skb_dequeue(&txqi->queue);
++      if (!skb)
++              return ERR_PTR(-EAGAIN);
++
++      atomic_dec(&sdata->txqs_len[ac]);
++      if (__netif_subqueue_stopped(sdata->dev, ac))
++              ieee80211_propagate_queue_wake(local, sdata->vif.hw_queue[ac]);
++
++      return skb;
++}
++EXPORT_SYMBOL(ieee80211_tx_dequeue);
++
+ static bool ieee80211_tx_frags(struct ieee80211_local *local,
+                              struct ieee80211_vif *vif,
+                              struct ieee80211_sta *sta,
+                              struct sk_buff_head *skbs,
+                              bool txpending)
+ {
+-      struct ieee80211_tx_control control;
+       struct sk_buff *skb, *tmp;
+       unsigned long flags;
+@@ -1265,10 +1328,9 @@ static bool ieee80211_tx_frags(struct ie
+               spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
+               info->control.vif = vif;
+-              control.sta = sta;
+               __skb_unlink(skb, skbs);
+-              drv_tx(local, &control, skb);
++              ieee80211_drv_tx(local, vif, sta, skb);
+       }
+       return true;
+--- a/net/mac80211/util.c
++++ b/net/mac80211/util.c
+@@ -308,6 +308,11 @@ void ieee80211_propagate_queue_wake(stru
+               for (ac = 0; ac < n_acs; ac++) {
+                       int ac_queue = sdata->vif.hw_queue[ac];
++                      if (local->ops->wake_tx_queue &&
++                          (atomic_read(&sdata->txqs_len[ac]) >
++                           local->hw.txq_ac_max_pending))
++                              continue;
++
+                       if (ac_queue == queue ||
+                           (sdata->vif.cab_queue == queue &&
+                            local->queue_stop_reasons[ac_queue] == 0 &&
+@@ -3307,3 +3312,36 @@ u8 *ieee80211_add_wmm_info_ie(u8 *buf, u
+       return buf;
+ }
++
++void ieee80211_init_tx_queue(struct ieee80211_sub_if_data *sdata,
++                           struct sta_info *sta,
++                           struct txq_info *txqi, int tid)
++{
++      skb_queue_head_init(&txqi->queue);
++      txqi->txq.vif = &sdata->vif;
++
++      if (sta) {
++              txqi->txq.sta = &sta->sta;
++              sta->sta.txq[tid] = &txqi->txq;
++              txqi->txq.ac = ieee802_1d_to_ac[tid & 7];
++      } else {
++              sdata->vif.txq = &txqi->txq;
++              txqi->txq.ac = IEEE80211_AC_BE;
++      }
++}
++
++void ieee80211_flush_tx_queue(struct ieee80211_local *local,
++                            struct ieee80211_txq *txq)
++{
++      struct txq_info *txqi = container_of(txq, struct txq_info, txq);
++      struct ieee80211_sub_if_data *sdata = vif_to_sdata(txq->vif);
++      struct sk_buff *skb;
++      int n = 0;
++
++      while ((skb = skb_dequeue(&txqi->queue)) != NULL) {
++              n++;
++              ieee80211_free_txskb(&local->hw, skb);
++      }
++
++      atomic_sub(n, &sdata->txqs_len[txq->ac]);
++}
diff --git a/package/kernel/mac80211/patches/301-ath5k-fix-AHB-kconfig-dependency.patch b/package/kernel/mac80211/patches/301-ath5k-fix-AHB-kconfig-dependency.patch
deleted file mode 100644 (file)
index 5db28be..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-From: Felix Fietkau <nbd@openwrt.org>
-Date: Sat, 27 Sep 2014 15:58:51 +0200
-Subject: [PATCH] ath5k: fix AHB kconfig dependency
-
-Signed-off-by: Felix Fietkau <nbd@openwrt.org>
----
-
---- a/drivers/net/wireless/ath/ath5k/Kconfig
-+++ b/drivers/net/wireless/ath/ath5k/Kconfig
-@@ -7,8 +7,8 @@ config ATH5K
-       select BACKPORT_LEDS_CLASS
-       select BACKPORT_NEW_LEDS
-       select BACKPORT_AVERAGE
--      select ATH5K_AHB if (ATHEROS_AR231X && !PCI)
--      select ATH5K_PCI if (!ATHEROS_AR231X && PCI)
-+      select ATH5K_AHB if ATHEROS_AR231X
-+      select ATH5K_PCI if !ATHEROS_AR231X
-       ---help---
-         This module adds support for wireless adapters based on
-         Atheros 5xxx chipset.
-@@ -55,14 +55,14 @@ config ATH5K_TRACER
- config ATH5K_AHB
-       bool "Atheros 5xxx AHB bus support"
--      depends on (ATHEROS_AR231X && !PCI)
-+      depends on ATHEROS_AR231X
-       ---help---
-         This adds support for WiSoC type chipsets of the 5xxx Atheros
-         family.
- config ATH5K_PCI
-       bool "Atheros 5xxx PCI bus support"
--      depends on (!ATHEROS_AR231X && PCI)
-+      depends on !ATHEROS_AR231X
-       ---help---
-         This adds support for PCI type chipsets of the 5xxx Atheros
-         family.
diff --git a/package/kernel/mac80211/patches/301-mac80211-lock-rate-control.patch b/package/kernel/mac80211/patches/301-mac80211-lock-rate-control.patch
new file mode 100644 (file)
index 0000000..6b69032
--- /dev/null
@@ -0,0 +1,125 @@
+From: Johannes Berg <johannes.berg@intel.com>
+Date: Wed, 11 Mar 2015 09:14:15 +0100
+Subject: [PATCH] mac80211: lock rate control
+
+Both minstrel (reported by Sven Eckelmann) and the iwlwifi rate
+control aren't properly taking concurrency into account. It's
+likely that the same is true for other rate control algorithms.
+
+In the case of minstrel this manifests itself in crashes when an
+update and other data access are run concurrently, for example
+when the stations change bandwidth or similar. In iwlwifi, this
+can cause firmware crashes.
+
+Since fixing all rate control algorithms will be very difficult,
+just provide locking for invocations. This protects the internal
+data structures the algorithms maintain.
+
+I've manipulated hostapd to test this, by having it change its
+advertised bandwidth roughly ever 150ms. At the same time, I'm
+running a flood ping between the client and the AP, which causes
+this race of update vs. get_rate/status to easily happen on the
+client. With this change, the system survives this test.
+
+Reported-by: Sven Eckelmann <sven@open-mesh.com>
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+---
+
+--- a/net/mac80211/rate.c
++++ b/net/mac80211/rate.c
+@@ -683,7 +683,13 @@ void rate_control_get_rate(struct ieee80
+       if (sdata->local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL)
+               return;
+-      ref->ops->get_rate(ref->priv, ista, priv_sta, txrc);
++      if (ista) {
++              spin_lock_bh(&sta->rate_ctrl_lock);
++              ref->ops->get_rate(ref->priv, ista, priv_sta, txrc);
++              spin_unlock_bh(&sta->rate_ctrl_lock);
++      } else {
++              ref->ops->get_rate(ref->priv, NULL, NULL, txrc);
++      }
+       if (sdata->local->hw.flags & IEEE80211_HW_SUPPORTS_RC_TABLE)
+               return;
+--- a/net/mac80211/rate.h
++++ b/net/mac80211/rate.h
+@@ -42,10 +42,12 @@ static inline void rate_control_tx_statu
+       if (!ref || !test_sta_flag(sta, WLAN_STA_RATE_CONTROL))
+               return;
++      spin_lock_bh(&sta->rate_ctrl_lock);
+       if (ref->ops->tx_status)
+               ref->ops->tx_status(ref->priv, sband, ista, priv_sta, skb);
+       else
+               ref->ops->tx_status_noskb(ref->priv, sband, ista, priv_sta, info);
++      spin_unlock_bh(&sta->rate_ctrl_lock);
+ }
+ static inline void
+@@ -64,7 +66,9 @@ rate_control_tx_status_noskb(struct ieee
+       if (WARN_ON_ONCE(!ref->ops->tx_status_noskb))
+               return;
++      spin_lock_bh(&sta->rate_ctrl_lock);
+       ref->ops->tx_status_noskb(ref->priv, sband, ista, priv_sta, info);
++      spin_unlock_bh(&sta->rate_ctrl_lock);
+ }
+ static inline void rate_control_rate_init(struct sta_info *sta)
+@@ -91,8 +95,10 @@ static inline void rate_control_rate_ini
+       sband = local->hw.wiphy->bands[chanctx_conf->def.chan->band];
++      spin_lock_bh(&sta->rate_ctrl_lock);
+       ref->ops->rate_init(ref->priv, sband, &chanctx_conf->def, ista,
+                           priv_sta);
++      spin_unlock_bh(&sta->rate_ctrl_lock);
+       rcu_read_unlock();
+       set_sta_flag(sta, WLAN_STA_RATE_CONTROL);
+ }
+@@ -115,18 +121,20 @@ static inline void rate_control_rate_upd
+                       return;
+               }
++              spin_lock_bh(&sta->rate_ctrl_lock);
+               ref->ops->rate_update(ref->priv, sband, &chanctx_conf->def,
+                                     ista, priv_sta, changed);
++              spin_unlock_bh(&sta->rate_ctrl_lock);
+               rcu_read_unlock();
+       }
+       drv_sta_rc_update(local, sta->sdata, &sta->sta, changed);
+ }
+ static inline void *rate_control_alloc_sta(struct rate_control_ref *ref,
+-                                         struct ieee80211_sta *sta,
+-                                         gfp_t gfp)
++                                         struct sta_info *sta, gfp_t gfp)
+ {
+-      return ref->ops->alloc_sta(ref->priv, sta, gfp);
++      spin_lock_init(&sta->rate_ctrl_lock);
++      return ref->ops->alloc_sta(ref->priv, &sta->sta, gfp);
+ }
+ static inline void rate_control_free_sta(struct sta_info *sta)
+--- a/net/mac80211/sta_info.c
++++ b/net/mac80211/sta_info.c
+@@ -280,7 +280,7 @@ static int sta_prepare_rate_control(stru
+       sta->rate_ctrl = local->rate_ctrl;
+       sta->rate_ctrl_priv = rate_control_alloc_sta(sta->rate_ctrl,
+-                                                   &sta->sta, gfp);
++                                                   sta, gfp);
+       if (!sta->rate_ctrl_priv)
+               return -ENOMEM;
+--- a/net/mac80211/sta_info.h
++++ b/net/mac80211/sta_info.h
+@@ -348,6 +348,7 @@ struct sta_info {
+       u8 ptk_idx;
+       struct rate_control_ref *rate_ctrl;
+       void *rate_ctrl_priv;
++      spinlock_t rate_ctrl_lock;
+       spinlock_t lock;
+       struct work_struct drv_deliver_wk;
diff --git a/package/kernel/mac80211/patches/302-ath9k-add-support-for-reporting-tx-power-to-mac80211.patch b/package/kernel/mac80211/patches/302-ath9k-add-support-for-reporting-tx-power-to-mac80211.patch
deleted file mode 100644 (file)
index 8bb41bd..0000000
+++ /dev/null
@@ -1,118 +0,0 @@
-From: Felix Fietkau <nbd@openwrt.org>
-Date: Wed, 22 Oct 2014 18:18:04 +0200
-Subject: [PATCH] ath9k: add support for reporting tx power to mac80211
-
-Track it per channel context instead of in the softc
-
-Signed-off-by: Felix Fietkau <nbd@openwrt.org>
----
-
---- a/drivers/net/wireless/ath/ath9k/ath9k.h
-+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
-@@ -347,6 +347,7 @@ struct ath_chanctx {
-       int flush_timeout;
-       u16 txpower;
-+      u16 cur_txpower;
-       bool offchannel;
-       bool stopped;
-       bool active;
-@@ -987,7 +988,6 @@ struct ath_softc {
-       u8 gtt_cnt;
-       u32 intrstatus;
-       u16 ps_flags; /* PS_* */
--      u16 curtxpow;
-       bool ps_enabled;
-       bool ps_idle;
-       short nbcnvifs;
---- a/drivers/net/wireless/ath/ath9k/init.c
-+++ b/drivers/net/wireless/ath/ath9k/init.c
-@@ -172,17 +172,20 @@ static void ath9k_reg_notifier(struct wi
-       ath_reg_notifier_apply(wiphy, request, reg);
-       /* Set tx power */
--      if (ah->curchan) {
--              sc->cur_chan->txpower = 2 * ah->curchan->chan->max_power;
--              ath9k_ps_wakeup(sc);
--              ath9k_hw_set_txpowerlimit(ah, sc->cur_chan->txpower, false);
--              sc->curtxpow = ath9k_hw_regulatory(ah)->power_limit;
--              /* synchronize DFS detector if regulatory domain changed */
--              if (sc->dfs_detector != NULL)
--                      sc->dfs_detector->set_dfs_domain(sc->dfs_detector,
--                                                       request->dfs_region);
--              ath9k_ps_restore(sc);
--      }
-+      if (!ah->curchan)
-+              return;
-+
-+      sc->cur_chan->txpower = 2 * ah->curchan->chan->max_power;
-+      ath9k_ps_wakeup(sc);
-+      ath9k_hw_set_txpowerlimit(ah, sc->cur_chan->txpower, false);
-+      ath9k_cmn_update_txpow(ah, sc->cur_chan->cur_txpower,
-+                             sc->cur_chan->txpower,
-+                             &sc->cur_chan->cur_txpower);
-+      /* synchronize DFS detector if regulatory domain changed */
-+      if (sc->dfs_detector != NULL)
-+              sc->dfs_detector->set_dfs_domain(sc->dfs_detector,
-+                                               request->dfs_region);
-+      ath9k_ps_restore(sc);
- }
- /*
---- a/drivers/net/wireless/ath/ath9k/main.c
-+++ b/drivers/net/wireless/ath/ath9k/main.c
-@@ -233,8 +233,9 @@ static bool ath_complete_reset(struct at
-       ath9k_calculate_summary_state(sc, sc->cur_chan);
-       ath_startrecv(sc);
--      ath9k_cmn_update_txpow(ah, sc->curtxpow,
--                             sc->cur_chan->txpower, &sc->curtxpow);
-+      ath9k_cmn_update_txpow(ah, sc->cur_chan->cur_txpower,
-+                             sc->cur_chan->txpower,
-+                             &sc->cur_chan->cur_txpower);
-       clear_bit(ATH_OP_HW_RESET, &common->op_flags);
-       if (!sc->cur_chan->offchannel && start) {
-@@ -1471,8 +1472,9 @@ static int ath9k_config(struct ieee80211
-       if (changed & IEEE80211_CONF_CHANGE_POWER) {
-               ath_dbg(common, CONFIG, "Set power: %d\n", conf->power_level);
-               sc->cur_chan->txpower = 2 * conf->power_level;
--              ath9k_cmn_update_txpow(ah, sc->curtxpow,
--                                     sc->cur_chan->txpower, &sc->curtxpow);
-+              ath9k_cmn_update_txpow(ah, sc->cur_chan->cur_txpower,
-+                                     sc->cur_chan->txpower,
-+                                     &sc->cur_chan->cur_txpower);
-       }
-       mutex_unlock(&sc->mutex);
-@@ -2594,6 +2596,24 @@ void ath9k_fill_chanctx_ops(void)
- #endif
-+static int ath9k_get_txpower(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
-+                           int *dbm)
-+{
-+      struct ath_softc *sc = hw->priv;
-+      struct ath_vif *avp = (void *)vif->drv_priv;
-+
-+      mutex_lock(&sc->mutex);
-+      if (avp->chanctx)
-+              *dbm = avp->chanctx->cur_txpower;
-+      else
-+              *dbm = sc->cur_chan->cur_txpower;
-+      mutex_unlock(&sc->mutex);
-+
-+      *dbm /= 2;
-+
-+      return 0;
-+}
-+
- struct ieee80211_ops ath9k_ops = {
-       .tx                 = ath9k_tx,
-       .start              = ath9k_start,
-@@ -2640,4 +2660,5 @@ struct ieee80211_ops ath9k_ops = {
- #endif
-       .sw_scan_start      = ath9k_sw_scan_start,
-       .sw_scan_complete   = ath9k_sw_scan_complete,
-+      .get_txpower        = ath9k_get_txpower,
- };
diff --git a/package/kernel/mac80211/patches/302-ath9k-restart-only-triggering-DFS-detector-line.patch b/package/kernel/mac80211/patches/302-ath9k-restart-only-triggering-DFS-detector-line.patch
new file mode 100644 (file)
index 0000000..e54e16e
--- /dev/null
@@ -0,0 +1,21 @@
+From: Zefir Kurtisi <zefir.kurtisi@neratec.com>
+Date: Tue, 10 Mar 2015 17:49:29 +0100
+Subject: [PATCH] ath9k: restart only triggering DFS detector line
+
+To support HT40 DFS mode, a triggering detector must
+reset only itself but not other detector lines.
+
+Signed-off-by: Zefir Kurtisi <zefir.kurtisi@neratec.com>
+---
+
+--- a/drivers/net/wireless/ath/dfs_pattern_detector.c
++++ b/drivers/net/wireless/ath/dfs_pattern_detector.c
+@@ -289,7 +289,7 @@ dpd_add_pulse(struct dfs_pattern_detecto
+                               "count=%d, count_false=%d\n",
+                               event->freq, pd->rs->type_id,
+                               ps->pri, ps->count, ps->count_falses);
+-                      channel_detector_reset(dpd, cd);
++                      pd->reset(pd, dpd->last_pulse_ts);
+                       return true;
+               }
+       }
diff --git a/package/kernel/mac80211/patches/303-ath10k-add-SURVEY_INFO_IN_USE-for-current-channel-on.patch b/package/kernel/mac80211/patches/303-ath10k-add-SURVEY_INFO_IN_USE-for-current-channel-on.patch
deleted file mode 100644 (file)
index 96cd78b..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-From: Felix Fietkau <nbd@openwrt.org>
-Date: Wed, 22 Oct 2014 18:44:03 +0200
-Subject: [PATCH] ath10k: add SURVEY_INFO_IN_USE for current channel on
- survey
-
-Signed-off-by: Felix Fietkau <nbd@openwrt.org>
----
-
---- a/drivers/net/wireless/ath/ath10k/mac.c
-+++ b/drivers/net/wireless/ath/ath10k/mac.c
-@@ -4044,6 +4044,9 @@ static int ath10k_get_survey(struct ieee
-       survey->channel = &sband->channels[idx];
-+      if (ar->rx_channel == survey->channel)
-+              survey->filled |= SURVEY_INFO_IN_USE;
-+
- exit:
-       mutex_unlock(&ar->conf_mutex);
-       return ret;
diff --git a/package/kernel/mac80211/patches/303-ath9k-add-DFS-support-for-extension-channel.patch b/package/kernel/mac80211/patches/303-ath9k-add-DFS-support-for-extension-channel.patch
new file mode 100644 (file)
index 0000000..ed268ea
--- /dev/null
@@ -0,0 +1,76 @@
+From: Zefir Kurtisi <zefir.kurtisi@neratec.com>
+Date: Tue, 10 Mar 2015 17:49:30 +0100
+Subject: [PATCH] ath9k: add DFS support for extension channel
+
+In HT40 modes, pulse events on primary and extension
+channel are processed individually. If valid, a pulse
+event will be fed into the detector
+* for primary frequency, or
+* for extension frequency (+/-20MHz based on HT40-mode)
+* or both
+
+With that, a 40MHz radar will result in two individual
+radar events.
+
+Signed-off-by: Zefir Kurtisi <zefir.kurtisi@neratec.com>
+---
+
+--- a/drivers/net/wireless/ath/ath9k/dfs.c
++++ b/drivers/net/wireless/ath/ath9k/dfs.c
+@@ -126,8 +126,19 @@ ath9k_postprocess_radar_event(struct ath
+       DFS_STAT_INC(sc, pulses_detected);
+       return true;
+ }
+-#undef PRI_CH_RADAR_FOUND
+-#undef EXT_CH_RADAR_FOUND
++
++static void
++ath9k_dfs_process_radar_pulse(struct ath_softc *sc, struct pulse_event *pe)
++{
++      struct dfs_pattern_detector *pd = sc->dfs_detector;
++      DFS_STAT_INC(sc, pulses_processed);
++      if (pd == NULL)
++              return;
++      if (!pd->add_pulse(pd, pe))
++              return;
++      DFS_STAT_INC(sc, radar_detected);
++      ieee80211_radar_detected(sc->hw);
++}
+ /*
+  * DFS: check PHY-error for radar pulse and feed the detector
+@@ -176,18 +187,21 @@ void ath9k_dfs_process_phyerr(struct ath
+       ard.pulse_length_pri = vdata_end[-3];
+       pe.freq = ah->curchan->channel;
+       pe.ts = mactime;
+-      if (ath9k_postprocess_radar_event(sc, &ard, &pe)) {
+-              struct dfs_pattern_detector *pd = sc->dfs_detector;
+-              ath_dbg(common, DFS,
+-                      "ath9k_dfs_process_phyerr: channel=%d, ts=%llu, "
+-                      "width=%d, rssi=%d, delta_ts=%llu\n",
+-                      pe.freq, pe.ts, pe.width, pe.rssi,
+-                      pe.ts - sc->dfs_prev_pulse_ts);
+-              sc->dfs_prev_pulse_ts = pe.ts;
+-              DFS_STAT_INC(sc, pulses_processed);
+-              if (pd != NULL && pd->add_pulse(pd, &pe)) {
+-                      DFS_STAT_INC(sc, radar_detected);
+-                      ieee80211_radar_detected(sc->hw);
+-              }
++      if (!ath9k_postprocess_radar_event(sc, &ard, &pe))
++              return;
++
++      ath_dbg(common, DFS,
++              "ath9k_dfs_process_phyerr: type=%d, freq=%d, ts=%llu, "
++              "width=%d, rssi=%d, delta_ts=%llu\n",
++              ard.pulse_bw_info, pe.freq, pe.ts, pe.width, pe.rssi,
++              pe.ts - sc->dfs_prev_pulse_ts);
++      sc->dfs_prev_pulse_ts = pe.ts;
++      if (ard.pulse_bw_info & PRI_CH_RADAR_FOUND)
++              ath9k_dfs_process_radar_pulse(sc, &pe);
++      if (ard.pulse_bw_info & EXT_CH_RADAR_FOUND) {
++              pe.freq += IS_CHAN_HT40PLUS(ah->curchan) ? 20 : -20;
++              ath9k_dfs_process_radar_pulse(sc, &pe);
+       }
+ }
++#undef PRI_CH_RADAR_FOUND
++#undef EXT_CH_RADAR_FOUND
diff --git a/package/kernel/mac80211/patches/304-ath9k-Fix-RTC_DERIVED_CLK-usage.patch b/package/kernel/mac80211/patches/304-ath9k-Fix-RTC_DERIVED_CLK-usage.patch
deleted file mode 100644 (file)
index a9205c0..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-From: Miaoqing Pan <miaoqing@qca.qualcomm.com>
-Date: Thu, 6 Nov 2014 10:52:23 +0530
-Subject: [PATCH] ath9k: Fix RTC_DERIVED_CLK usage
-
-Based on the reference clock, which could be 25MHz or 40MHz,
-AR_RTC_DERIVED_CLK is programmed differently for AR9340 and AR9550.
-But, when a chip reset is done, processing the initvals
-sets the register back to the default value.
-
-Fix this by moving the code in ath9k_hw_init_pll() to
-ar9003_hw_override_ini(). Also, do this override for AR9531.
-
-Cc: stable@vger.kernel.org
-Signed-off-by: Miaoqing Pan <miaoqing@qca.qualcomm.com>
-Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
----
-
---- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
-+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
-@@ -664,6 +664,19 @@ static void ar9003_hw_override_ini(struc
-               ah->enabled_cals |= TX_CL_CAL;
-       else
-               ah->enabled_cals &= ~TX_CL_CAL;
-+
-+      if (AR_SREV_9340(ah) || AR_SREV_9531(ah) || AR_SREV_9550(ah)) {
-+              if (ah->is_clk_25mhz) {
-+                      REG_WRITE(ah, AR_RTC_DERIVED_CLK, 0x17c << 1);
-+                      REG_WRITE(ah, AR_SLP32_MODE, 0x0010f3d7);
-+                      REG_WRITE(ah, AR_SLP32_INC, 0x0001e7ae);
-+              } else {
-+                      REG_WRITE(ah, AR_RTC_DERIVED_CLK, 0x261 << 1);
-+                      REG_WRITE(ah, AR_SLP32_MODE, 0x0010f400);
-+                      REG_WRITE(ah, AR_SLP32_INC, 0x0001e800);
-+              }
-+              udelay(100);
-+      }
- }
- static void ar9003_hw_prog_ini(struct ath_hw *ah,
---- a/drivers/net/wireless/ath/ath9k/hw.c
-+++ b/drivers/net/wireless/ath/ath9k/hw.c
-@@ -870,19 +870,6 @@ static void ath9k_hw_init_pll(struct ath
-       udelay(RTC_PLL_SETTLE_DELAY);
-       REG_WRITE(ah, AR_RTC_SLEEP_CLK, AR_RTC_FORCE_DERIVED_CLK);
--
--      if (AR_SREV_9340(ah) || AR_SREV_9550(ah)) {
--              if (ah->is_clk_25mhz) {
--                      REG_WRITE(ah, AR_RTC_DERIVED_CLK, 0x17c << 1);
--                      REG_WRITE(ah, AR_SLP32_MODE, 0x0010f3d7);
--                      REG_WRITE(ah,  AR_SLP32_INC, 0x0001e7ae);
--              } else {
--                      REG_WRITE(ah, AR_RTC_DERIVED_CLK, 0x261 << 1);
--                      REG_WRITE(ah, AR_SLP32_MODE, 0x0010f400);
--                      REG_WRITE(ah,  AR_SLP32_INC, 0x0001e800);
--              }
--              udelay(100);
--      }
- }
- static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah,
diff --git a/package/kernel/mac80211/patches/304-ath9k-allow-40MHz-radar-detection-width.patch b/package/kernel/mac80211/patches/304-ath9k-allow-40MHz-radar-detection-width.patch
new file mode 100644 (file)
index 0000000..e1eab64
--- /dev/null
@@ -0,0 +1,19 @@
+From: Zefir Kurtisi <zefir.kurtisi@neratec.com>
+Date: Tue, 10 Mar 2015 17:49:31 +0100
+Subject: [PATCH] ath9k: allow 40MHz radar detection width
+
+Signed-off-by: Zefir Kurtisi <zefir.kurtisi@neratec.com>
+---
+
+--- a/drivers/net/wireless/ath/ath9k/init.c
++++ b/drivers/net/wireless/ath/ath9k/init.c
+@@ -763,7 +763,8 @@ static const struct ieee80211_iface_comb
+               .num_different_channels = 1,
+               .beacon_int_infra_match = true,
+               .radar_detect_widths =  BIT(NL80211_CHAN_WIDTH_20_NOHT) |
+-                                      BIT(NL80211_CHAN_WIDTH_20),
++                                      BIT(NL80211_CHAN_WIDTH_20) |
++                                      BIT(NL80211_CHAN_WIDTH_40),
+       }
+ #endif
+ };
diff --git a/package/kernel/mac80211/patches/305-ath5k-channel-change-fix.patch b/package/kernel/mac80211/patches/305-ath5k-channel-change-fix.patch
new file mode 100644 (file)
index 0000000..afed7b4
--- /dev/null
@@ -0,0 +1,137 @@
+From: Sergey Ryazanov <ryazanov.s.a@gmail.com>
+Date: Wed, 4 Mar 2015 05:12:10 +0300
+Subject: [PATCH] ath5k: channel change fix
+
+ath5k updates the channel pointer and after that it stops the Rx logic
+and apply channel to HW. In case of channel switch, such sequence
+creates a small window when a frame, which is received on the old
+channel is considered as a frame received on the new one.
+
+The most notable consequence of this situation occurs during the switch
+from 2 GHz band (CCK+OFDM) to the 5GHz band (OFDM-only). Frame received
+with CCK rate, e.g. beacon received at the 1mbps, causes the following
+warning:
+
+  WARNING: at ath5k/base.c:589 ath5k_tasklet_rx+0x318/0x6ec [ath5k]()
+  invalid hw_rix: 1a
+  [..]
+  Call Trace:
+  [<802656a8>] show_stack+0x48/0x70
+  [<802dd92c>] warn_slowpath_common+0x88/0xbc
+  [<802dd98c>] warn_slowpath_fmt+0x2c/0x38
+  [<81b51be8>] ath5k_tasklet_rx+0x318/0x6ec [ath5k]
+  [<8028ac64>] tasklet_action+0x8c/0xf0
+  [<80075804>] __do_softirq+0x180/0x32c
+  [<80196ce8>] irq_exit+0x54/0x70
+  [<80041848>] ret_from_irq+0x0/0x4
+  [<80182fdc>] ioread32+0x4/0xc
+  [<81b4c42c>] ath5k_hw_set_sleep_clock+0x2ec/0x474 [ath5k]
+  [<81b4cf28>] ath5k_hw_reset+0x50/0xeb8 [ath5k]
+  [<81b50900>] ath5k_reset+0xd4/0x310 [ath5k]
+  [<81b557e8>] ath5k_config+0x4c/0x104 [ath5k]
+  [<80d01770>] ieee80211_hw_config+0x2f4/0x35c [mac80211]
+  [<80d09aa8>] ieee80211_scan_work+0x2e4/0x414 [mac80211]
+  [<8022c3f4>] process_one_work+0x28c/0x400
+  [<802df8f8>] worker_thread+0x258/0x3c0
+  [<801b5710>] kthread+0xe0/0xec
+  [<800418a8>] ret_from_kernel_thread+0x14/0x1c
+
+The easiest way to reproduce this warning is to run scan with dualband
+NIC in noisy environments, when the channel 11 runs multiple APs. In my
+tests if the APs num >= 12, the warning appears in the first few
+seconds of scanning.
+
+In order to fix this, the Rx disable code moved to a higher level and
+placed before the channel pointer update. This is also makes the code a
+bit more symmetrical, since we disable and enable the Rx in the same
+function.
+
+In fact, at the pointer update time new frames should not appear,
+because interrupt generation at this point should already be disabled.
+The next patch should address this issue.
+
+CC: Jiri Slaby <jirislaby@gmail.com>
+CC: Nick Kossifidis <mickflemm@gmail.com>
+CC: Luis R. Rodriguez <mcgrof@do-not-panic.com>
+Reported-by: Christophe Prevotaux <cprevotaux@nltinc.com>
+Tested-by: Christophe Prevotaux <cprevotaux@nltinc.com>
+Tested-by: Eric Bree <ebree@nltinc.com>
+Signed-off-by: Sergey Ryazanov <ryazanov.s.a@gmail.com>
+---
+
+--- a/drivers/net/wireless/ath/ath5k/base.c
++++ b/drivers/net/wireless/ath/ath5k/base.c
+@@ -2858,7 +2858,7 @@ ath5k_reset(struct ath5k_hw *ah, struct 
+ {
+       struct ath_common *common = ath5k_hw_common(ah);
+       int ret, ani_mode;
+-      bool fast;
++      bool fast = chan && modparam_fastchanswitch ? 1 : 0;
+       ATH5K_DBG(ah, ATH5K_DEBUG_RESET, "resetting\n");
+@@ -2876,11 +2876,29 @@ ath5k_reset(struct ath5k_hw *ah, struct 
+        * so we should also free any remaining
+        * tx buffers */
+       ath5k_drain_tx_buffs(ah);
++
++      /* Stop PCU */
++      ath5k_hw_stop_rx_pcu(ah);
++
++      /* Stop DMA
++       *
++       * Note: If DMA didn't stop continue
++       * since only a reset will fix it.
++       */
++      ret = ath5k_hw_dma_stop(ah);
++
++      /* RF Bus grant won't work if we have pending
++       * frames
++       */
++      if (ret && fast) {
++              ATH5K_DBG(ah, ATH5K_DEBUG_RESET,
++                        "DMA didn't stop, falling back to normal reset\n");
++              fast = false;
++      }
++
+       if (chan)
+               ah->curchan = chan;
+-      fast = ((chan != NULL) && modparam_fastchanswitch) ? 1 : 0;
+-
+       ret = ath5k_hw_reset(ah, ah->opmode, ah->curchan, fast, skip_pcu);
+       if (ret) {
+               ATH5K_ERR(ah, "can't reset hardware (%d)\n", ret);
+--- a/drivers/net/wireless/ath/ath5k/reset.c
++++ b/drivers/net/wireless/ath/ath5k/reset.c
+@@ -1169,30 +1169,6 @@ ath5k_hw_reset(struct ath5k_hw *ah, enum
+       if (ah->ah_version == AR5K_AR5212)
+               ath5k_hw_set_sleep_clock(ah, false);
+-      /*
+-       * Stop PCU
+-       */
+-      ath5k_hw_stop_rx_pcu(ah);
+-
+-      /*
+-       * Stop DMA
+-       *
+-       * Note: If DMA didn't stop continue
+-       * since only a reset will fix it.
+-       */
+-      ret = ath5k_hw_dma_stop(ah);
+-
+-      /* RF Bus grant won't work if we have pending
+-       * frames */
+-      if (ret && fast) {
+-              ATH5K_DBG(ah, ATH5K_DEBUG_RESET,
+-                      "DMA didn't stop, falling back to normal reset\n");
+-              fast = false;
+-              /* Non fatal, just continue with
+-               * normal reset */
+-              ret = 0;
+-      }
+-
+       mode = channel->hw_value;
+       switch (mode) {
+       case AR5K_MODE_11A:
diff --git a/package/kernel/mac80211/patches/305-b43-fix-NULL-pointer-dereference-in-b43_phy_copy.patch b/package/kernel/mac80211/patches/305-b43-fix-NULL-pointer-dereference-in-b43_phy_copy.patch
deleted file mode 100644 (file)
index 649ed6b..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-From: Hauke Mehrtens <hauke@hauke-m.de>
-Date: Wed, 5 Nov 2014 23:31:07 +0100
-Subject: [PATCH] b43: fix NULL pointer dereference in b43_phy_copy()
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-phy_read and phy_write are not set for every phy any more sine this:
-commit d342b95dd735014a590f9051b1ba227eb54ca8f6
-Author: RafaÅ‚ MiÅ‚ecki <zajec5@gmail.com>
-Date:   Thu Jul 31 21:59:43 2014 +0200
-
-    b43: don't duplicate common PHY read/write ops
-
-b43_phy_copy() accesses phy_read and phy_write directly and will fail
-with some phys. This patch fixes the regression by using the
-b43_phy_read() and b43_phy_write() functions which should be used for
-read and write access.
-
-This should fix this bug report:
-https://bugzilla.kernel.org/show_bug.cgi?id=87731
-
-Reported-by: Volker Kempter <v.kempter@pe.tu-clausthal.de>
-Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
----
-
---- a/drivers/net/wireless/b43/phy_common.c
-+++ b/drivers/net/wireless/b43/phy_common.c
-@@ -301,8 +301,7 @@ void b43_phy_write(struct b43_wldev *dev
- void b43_phy_copy(struct b43_wldev *dev, u16 destreg, u16 srcreg)
- {
-       assert_mac_suspended(dev);
--      dev->phy.ops->phy_write(dev, destreg,
--              dev->phy.ops->phy_read(dev, srcreg));
-+      b43_phy_write(dev, destreg, b43_phy_read(dev, srcreg));
- }
- void b43_phy_mask(struct b43_wldev *dev, u16 offset, u16 mask)
diff --git a/package/kernel/mac80211/patches/306-ath5k-fix-reset-race.patch b/package/kernel/mac80211/patches/306-ath5k-fix-reset-race.patch
new file mode 100644 (file)
index 0000000..3990765
--- /dev/null
@@ -0,0 +1,96 @@
+From: Sergey Ryazanov <ryazanov.s.a@gmail.com>
+Date: Wed, 4 Mar 2015 05:12:11 +0300
+Subject: [PATCH] ath5k: fix reset race
+
+To prepare for reset ath5k should finish all asynchronous tasks. At
+first, it disables the interrupt generation, then it waits for the
+interrupt handler and tasklets completion, and then proceeds to the HW
+configuration update. But it does not consider that the interrupt
+handler or tasklet re-enables the interrupt generation. And we fall in a
+situation when ath5k assumes that interrupts are disabled, but it is
+not.
+
+This can lead to different consequences, such as reception of the frame,
+when we do not expect it. Under certain circumstances, this can lead to
+the following warning:
+
+  WARNING: at ath5k/base.c:589 ath5k_tasklet_rx+0x318/0x6ec [ath5k]()
+  invalid hw_rix: 1a
+  [..]
+  Call Trace:
+  [<802656a8>] show_stack+0x48/0x70
+  [<802dd92c>] warn_slowpath_common+0x88/0xbc
+  [<802dd98c>] warn_slowpath_fmt+0x2c/0x38
+  [<81b51be8>] ath5k_tasklet_rx+0x318/0x6ec [ath5k]
+  [<8028ac64>] tasklet_action+0x8c/0xf0
+  [<80075804>] __do_softirq+0x180/0x32c
+  [<80196ce8>] irq_exit+0x54/0x70
+  [<80041848>] ret_from_irq+0x0/0x4
+  [<80182fdc>] ioread32+0x4/0xc
+  [<81b4c42c>] ath5k_hw_set_sleep_clock+0x2ec/0x474 [ath5k]
+  [<81b4cf28>] ath5k_hw_reset+0x50/0xeb8 [ath5k]
+  [<81b50900>] ath5k_reset+0xd4/0x310 [ath5k]
+  [<81b557e8>] ath5k_config+0x4c/0x104 [ath5k]
+  [<80d01770>] ieee80211_hw_config+0x2f4/0x35c [mac80211]
+  [<80d09aa8>] ieee80211_scan_work+0x2e4/0x414 [mac80211]
+  [<8022c3f4>] process_one_work+0x28c/0x400
+  [<802df8f8>] worker_thread+0x258/0x3c0
+  [<801b5710>] kthread+0xe0/0xec
+  [<800418a8>] ret_from_kernel_thread+0x14/0x1c
+
+Fix this issue by adding a new status flag, which forbids to re-enable
+the interrupt generation until the HW configuration is completed.
+
+Note: previous patch, which reorders the Rx disable code helps to avoid
+the above warning, but not fixes the root cause of unexpected frame
+receiving.
+
+CC: Jiri Slaby <jirislaby@gmail.com>
+CC: Nick Kossifidis <mickflemm@gmail.com>
+CC: Luis R. Rodriguez <mcgrof@do-not-panic.com>
+Reported-by: Christophe Prevotaux <cprevotaux@nltinc.com>
+Tested-by: Christophe Prevotaux <cprevotaux@nltinc.com>
+Tested-by: Eric Bree <ebree@nltinc.com>
+Signed-off-by: Sergey Ryazanov <ryazanov.s.a@gmail.com>
+---
+
+--- a/drivers/net/wireless/ath/ath5k/ath5k.h
++++ b/drivers/net/wireless/ath/ath5k/ath5k.h
+@@ -1283,6 +1283,7 @@ struct ath5k_hw {
+ #define ATH_STAT_PROMISC      1
+ #define ATH_STAT_LEDSOFT      2               /* enable LED gpio status */
+ #define ATH_STAT_STARTED      3               /* opened & irqs enabled */
++#define ATH_STAT_RESET                4               /* hw reset */
+       unsigned int            filter_flags;   /* HW flags, AR5K_RX_FILTER_* */
+       unsigned int            fif_filter_flags; /* Current FIF_* filter flags */
+--- a/drivers/net/wireless/ath/ath5k/base.c
++++ b/drivers/net/wireless/ath/ath5k/base.c
+@@ -1523,6 +1523,9 @@ ath5k_set_current_imask(struct ath5k_hw 
+       enum ath5k_int imask;
+       unsigned long flags;
++      if (test_bit(ATH_STAT_RESET, ah->status))
++              return;
++
+       spin_lock_irqsave(&ah->irqlock, flags);
+       imask = ah->imask;
+       if (ah->rx_pending)
+@@ -2862,6 +2865,8 @@ ath5k_reset(struct ath5k_hw *ah, struct 
+       ATH5K_DBG(ah, ATH5K_DEBUG_RESET, "resetting\n");
++      __set_bit(ATH_STAT_RESET, ah->status);
++
+       ath5k_hw_set_imr(ah, 0);
+       synchronize_irq(ah->irq);
+       ath5k_stop_tasklets(ah);
+@@ -2952,6 +2957,8 @@ ath5k_reset(struct ath5k_hw *ah, struct 
+        */
+ /*    ath5k_chan_change(ah, c); */
++      __clear_bit(ATH_STAT_RESET, ah->status);
++
+       ath5k_beacon_config(ah);
+       /* intrs are enabled by ath5k_beacon_config */
diff --git a/package/kernel/mac80211/patches/306-ath9k-fix-misc-debugfs-when-not-using-chan-context.patch b/package/kernel/mac80211/patches/306-ath9k-fix-misc-debugfs-when-not-using-chan-context.patch
deleted file mode 100644 (file)
index 30b3dcf..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-From: Ben Greear <greearb@candelatech.com>
-Date: Tue, 4 Nov 2014 15:22:49 -0800
-Subject: [PATCH] ath9k: fix misc debugfs when not using chan context
-
-When channel-context is not enabled, all vifs belong to
-the first context, but it is not configured as 'assigned'.
-
-Fix misc debugfs file to print out info for non-assigned
-contexts, and also print whether ctx is assigned or not.
-
-Signed-off-by: Ben Greear <greearb@candelatech.com>
----
-
---- a/drivers/net/wireless/ath/ath9k/debug.c
-+++ b/drivers/net/wireless/ath/ath9k/debug.c
-@@ -828,13 +828,14 @@ static ssize_t read_file_misc(struct fil
-       i = 0;
-       ath_for_each_chanctx(sc, ctx) {
--              if (!ctx->assigned || list_empty(&ctx->vifs))
-+              if (list_empty(&ctx->vifs))
-                       continue;
-               ath9k_calculate_iter_data(sc, ctx, &iter_data);
-               len += scnprintf(buf + len, sizeof(buf) - len,
--                      "VIF-COUNTS: CTX %i AP: %i STA: %i MESH: %i WDS: %i",
--                      i++, iter_data.naps, iter_data.nstations,
-+                      "VIFS: CTX %i(%i) AP: %i STA: %i MESH: %i WDS: %i",
-+                      i++, (int)(ctx->assigned), iter_data.naps,
-+                      iter_data.nstations,
-                       iter_data.nmeshes, iter_data.nwds);
-               len += scnprintf(buf + len, sizeof(buf) - len,
-                       " ADHOC: %i TOTAL: %hi BEACON-VIF: %hi\n",
diff --git a/package/kernel/mac80211/patches/307-ath9k-fix-regression-in-bssidmask-calculation.patch b/package/kernel/mac80211/patches/307-ath9k-fix-regression-in-bssidmask-calculation.patch
deleted file mode 100644 (file)
index d596392..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-From: Ben Greear <greearb@candelatech.com>
-Date: Tue, 4 Nov 2014 15:22:50 -0800
-Subject: [PATCH] ath9k: fix regression in bssidmask calculation
-
-The commit that went into 3.17:
-
-    ath9k: Summarize hw state per channel context
-
-    Group and set hw state (opmode, primary_sta, beacon conf) per
-    channel context instead of whole list of vifs. This would allow
-    each channel context to run in different mode (STA/AP).
-
-    Signed-off-by: Felix Fietkau <nbd@openwrt.org>
-    Signed-off-by: Rajkumar Manoharan <rmanohar@qti.qualcomm.com>
-    Signed-off-by: John W. Linville <linville@tuxdriver.com>
-
-broke multi-vif configuration due to not properly calculating
-the bssid mask.
-
-The test case that caught this was:
-
- create wlan0 and sta0-4 (6 total), not sure how much that matters.
- associate all 6 (works fine)
- disconnect 5 of them, leaving sta0 up
- Start trying to bring up the other 5 one at a time.  It will
- fail, with iw events looking like this (in these logs, several
- sta are trying to come up, but symptom is the same with just one)
-
-The patch causing the regression made quite a few changes, but
-the part I think caused this particular problem was not
-recalculating the bssid mask when adding and removing interfaces.
-
-Re-adding those calls fixes my test case.  Fix bad comment
-as well.
-
-Signed-off-by: Ben Greear <greearb@candelatech.com>
----
-
---- a/drivers/net/wireless/ath/ath9k/main.c
-+++ b/drivers/net/wireless/ath/ath9k/main.c
-@@ -994,9 +994,8 @@ void ath9k_calculate_iter_data(struct at
-       struct ath_vif *avp;
-       /*
--       * Pick the MAC address of the first interface as the new hardware
--       * MAC address. The hardware will use it together with the BSSID mask
--       * when matching addresses.
-+       * The hardware will use primary station addr together with the
-+       * BSSID mask when matching addresses.
-        */
-       memset(iter_data, 0, sizeof(*iter_data));
-       memset(&iter_data->mask, 0xff, ETH_ALEN);
-@@ -1225,6 +1224,8 @@ static int ath9k_add_interface(struct ie
-               list_add_tail(&avp->list, &avp->chanctx->vifs);
-       }
-+      ath9k_calculate_summary_state(sc, avp->chanctx);
-+
-       ath9k_assign_hw_queues(hw, vif);
-       an->sc = sc;
-@@ -1294,6 +1295,8 @@ static void ath9k_remove_interface(struc
-       ath_tx_node_cleanup(sc, &avp->mcast_node);
-+      ath9k_calculate_summary_state(sc, avp->chanctx);
-+
-       mutex_unlock(&sc->mutex);
- }
diff --git a/package/kernel/mac80211/patches/308-rt2x00-do-not-align-payload-on-modern-H-W.patch b/package/kernel/mac80211/patches/308-rt2x00-do-not-align-payload-on-modern-H-W.patch
deleted file mode 100644 (file)
index 384a0be..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-From: Stanislaw Gruszka <sgruszka@redhat.com>
-Date: Sun, 2 Nov 2014 13:38:47 +0100
-Subject: [PATCH] rt2x00: do not align payload on modern H/W
-
-RT2800 and newer hardware require padding between header and payload if
-header length is not multiple of 4.
-
-For historical reasons we also align payload to to 4 bytes boundary, but
-such alignment is not needed on modern H/W.
-
-Patch improve performance on embedded CPUs and _possibly_ fixes
-skb_under_panic problems reported from time to time:
-
-https://bugzilla.kernel.org/show_bug.cgi?id=84911
-https://bugzilla.kernel.org/show_bug.cgi?id=72471
-http://marc.info/?l=linux-wireless&m=139108549530402&w=2
-https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1087591
-
-But we can not explain or otherwise confirm the patch fixes this panic
-issue for sure.
-
-Originally-From: Helmut Schaa <helmut.schaa@googlemail.com>
-Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
----
-
---- a/drivers/net/wireless/rt2x00/rt2x00queue.c
-+++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
-@@ -158,55 +158,29 @@ void rt2x00queue_align_frame(struct sk_b
-       skb_trim(skb, frame_length);
- }
--void rt2x00queue_insert_l2pad(struct sk_buff *skb, unsigned int header_length)
-+/*
-+ * H/W needs L2 padding between the header and the paylod if header size
-+ * is not 4 bytes aligned.
-+ */
-+void rt2x00queue_insert_l2pad(struct sk_buff *skb, unsigned int hdr_len)
- {
--      unsigned int payload_length = skb->len - header_length;
--      unsigned int header_align = ALIGN_SIZE(skb, 0);
--      unsigned int payload_align = ALIGN_SIZE(skb, header_length);
--      unsigned int l2pad = payload_length ? L2PAD_SIZE(header_length) : 0;
-+      unsigned int l2pad = (skb->len > hdr_len) ? L2PAD_SIZE(hdr_len) : 0;
--      /*
--       * Adjust the header alignment if the payload needs to be moved more
--       * than the header.
--       */
--      if (payload_align > header_align)
--              header_align += 4;
--
--      /* There is nothing to do if no alignment is needed */
--      if (!header_align)
-+      if (!l2pad)
-               return;
--      /* Reserve the amount of space needed in front of the frame */
--      skb_push(skb, header_align);
--
--      /*
--       * Move the header.
--       */
--      memmove(skb->data, skb->data + header_align, header_length);
--
--      /* Move the payload, if present and if required */
--      if (payload_length && payload_align)
--              memmove(skb->data + header_length + l2pad,
--                      skb->data + header_length + l2pad + payload_align,
--                      payload_length);
--
--      /* Trim the skb to the correct size */
--      skb_trim(skb, header_length + l2pad + payload_length);
-+      skb_push(skb, l2pad);
-+      memmove(skb->data, skb->data + l2pad, hdr_len);
- }
--void rt2x00queue_remove_l2pad(struct sk_buff *skb, unsigned int header_length)
-+void rt2x00queue_remove_l2pad(struct sk_buff *skb, unsigned int hdr_len)
- {
--      /*
--       * L2 padding is only present if the skb contains more than just the
--       * IEEE 802.11 header.
--       */
--      unsigned int l2pad = (skb->len > header_length) ?
--                              L2PAD_SIZE(header_length) : 0;
-+      unsigned int l2pad = (skb->len > hdr_len) ? L2PAD_SIZE(hdr_len) : 0;
-       if (!l2pad)
-               return;
--      memmove(skb->data + l2pad, skb->data, header_length);
-+      memmove(skb->data + l2pad, skb->data, hdr_len);
-       skb_pull(skb, l2pad);
- }
diff --git a/package/kernel/mac80211/patches/309-ath9k-prevent-early-IRQs-from-accessing-hardware.patch b/package/kernel/mac80211/patches/309-ath9k-prevent-early-IRQs-from-accessing-hardware.patch
deleted file mode 100644 (file)
index 6af94c8..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-From: Felix Fietkau <nbd@openwrt.org>
-Date: Thu, 13 Nov 2014 18:27:47 +0100
-Subject: [PATCH] ath9k: prevent early IRQs from accessing hardware
-
-IRQs are suppressed if ah == NULL and ATH_OP_INVALID being set in
-common->op_flags. Close a short time window between those two.
-
-Signed-off-by: Felix Fietkau <nbd@openwrt.org>
----
-
---- a/drivers/net/wireless/ath/ath9k/init.c
-+++ b/drivers/net/wireless/ath/ath9k/init.c
-@@ -513,10 +513,14 @@ static int ath9k_init_softc(u16 devid, s
-       ah->reg_ops.read = ath9k_ioread32;
-       ah->reg_ops.write = ath9k_iowrite32;
-       ah->reg_ops.rmw = ath9k_reg_rmw;
--      sc->sc_ah = ah;
-       pCap = &ah->caps;
-       common = ath9k_hw_common(ah);
-+
-+      /* Will be cleared in ath9k_start() */
-+      set_bit(ATH_OP_INVALID, &common->op_flags);
-+
-+      sc->sc_ah = ah;
-       sc->dfs_detector = dfs_pattern_detector_init(common, NL80211_DFS_UNSET);
-       sc->tx99_power = MAX_RATE_POWER + 1;
-       init_waitqueue_head(&sc->tx_wait);
-@@ -876,9 +880,6 @@ int ath9k_init_device(u16 devid, struct 
-       common = ath9k_hw_common(ah);
-       ath9k_set_hw_capab(sc, hw);
--      /* Will be cleared in ath9k_start() */
--      set_bit(ATH_OP_INVALID, &common->op_flags);
--
-       /* Initialize regulatory */
-       error = ath_regd_init(&common->regulatory, sc->hw->wiphy,
-                             ath9k_reg_notifier);
diff --git a/package/kernel/mac80211/patches/310-ath9k-set-ATH_OP_INVALID-before-disabling-hardware.patch b/package/kernel/mac80211/patches/310-ath9k-set-ATH_OP_INVALID-before-disabling-hardware.patch
deleted file mode 100644 (file)
index c382e5d..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-From: Felix Fietkau <nbd@openwrt.org>
-Date: Thu, 13 Nov 2014 18:29:00 +0100
-Subject: [PATCH] ath9k: set ATH_OP_INVALID before disabling hardware
-
-Closes another small IRQ handler race
-
-Signed-off-by: Felix Fietkau <nbd@openwrt.org>
----
-
---- a/drivers/net/wireless/ath/ath9k/main.c
-+++ b/drivers/net/wireless/ath/ath9k/main.c
-@@ -885,6 +885,9 @@ static void ath9k_stop(struct ieee80211_
-                                                   &sc->cur_chan->chandef);
-       ath9k_hw_reset(ah, ah->curchan, ah->caldata, false);
-+
-+      set_bit(ATH_OP_INVALID, &common->op_flags);
-+
-       ath9k_hw_phy_disable(ah);
-       ath9k_hw_configpcipowersave(ah, true);
-@@ -893,7 +896,6 @@ static void ath9k_stop(struct ieee80211_
-       ath9k_ps_restore(sc);
--      set_bit(ATH_OP_INVALID, &common->op_flags);
-       sc->ps_idle = prev_idle;
-       mutex_unlock(&sc->mutex);
diff --git a/package/kernel/mac80211/patches/311-ath9k-do-not-access-hardware-on-IRQs-during-reset.patch b/package/kernel/mac80211/patches/311-ath9k-do-not-access-hardware-on-IRQs-during-reset.patch
deleted file mode 100644 (file)
index 2994632..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-From: Felix Fietkau <nbd@openwrt.org>
-Date: Thu, 13 Nov 2014 18:29:26 +0100
-Subject: [PATCH] ath9k: do not access hardware on IRQs during reset
-
-Instead of killing interrupts during reset when the first one happens,
-kill them before issuing the reset.
-This fixes an easy to reproduce crash with multiple cards sharing the
-same IRQ.
-
-Cc: stable@vger.kernel.org
-Signed-off-by: Felix Fietkau <nbd@openwrt.org>
----
-
---- a/drivers/net/wireless/ath/ath9k/main.c
-+++ b/drivers/net/wireless/ath/ath9k/main.c
-@@ -512,16 +512,13 @@ irqreturn_t ath_isr(int irq, void *dev)
-       if (!ah || test_bit(ATH_OP_INVALID, &common->op_flags))
-               return IRQ_NONE;
--      /* shared irq, not for us */
-+      if (!AR_SREV_9100(ah) && test_bit(ATH_OP_HW_RESET, &common->op_flags))
-+              return IRQ_NONE;
-+      /* shared irq, not for us */
-       if (!ath9k_hw_intrpend(ah))
-               return IRQ_NONE;
--      if (test_bit(ATH_OP_HW_RESET, &common->op_flags)) {
--              ath9k_hw_kill_interrupts(ah);
--              return IRQ_HANDLED;
--      }
--
-       /*
-        * Figure out the reason(s) for the interrupt.  Note
-        * that the hal returns a pseudo-ISR that may include
-@@ -532,6 +529,9 @@ irqreturn_t ath_isr(int irq, void *dev)
-       ath9k_debug_sync_cause(sc, sync_cause);
-       status &= ah->imask;    /* discard unasked-for bits */
-+      if (AR_SREV_9100(ah) && test_bit(ATH_OP_HW_RESET, &common->op_flags))
-+              return IRQ_HANDLED;
-+
-       /*
-        * If there are no status bits set, then this interrupt was not
-        * for me (should have been caught above).
-@@ -613,6 +613,7 @@ int ath_reset(struct ath_softc *sc, stru
-       struct ath_common *common = ath9k_hw_common(sc->sc_ah);
-       int r;
-+      ath9k_hw_kill_interrupts(sc->sc_ah);
-       set_bit(ATH_OP_HW_RESET, &common->op_flags);
-       ath9k_ps_wakeup(sc);
-@@ -633,6 +634,7 @@ void ath9k_queue_reset(struct ath_softc 
- #ifdef CPTCFG_ATH9K_DEBUGFS
-       RESET_STAT_INC(sc, type);
- #endif
-+      ath9k_hw_kill_interrupts(sc->sc_ah);
-       set_bit(ATH_OP_HW_RESET, &common->op_flags);
-       ieee80211_queue_work(sc->hw, &sc->hw_reset_work);
- }
diff --git a/package/kernel/mac80211/patches/312-mac80211-skip-legacy-rate-mask-handling-for-VHT-rate.patch b/package/kernel/mac80211/patches/312-mac80211-skip-legacy-rate-mask-handling-for-VHT-rate.patch
deleted file mode 100644 (file)
index 23957af..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-From: Felix Fietkau <nbd@openwrt.org>
-Date: Sat, 15 Nov 2014 03:45:56 +0100
-Subject: [PATCH] mac80211: skip legacy rate mask handling for VHT rates
-
-The rate mask code currently assumes that a rate is legacy if
-IEEE80211_TX_RC_MCS is not set. This might be the cause of bogus VHT
-rates being reported with minstrel_ht.
-
-Signed-off-by: Felix Fietkau <nbd@openwrt.org>
----
-
---- a/net/mac80211/rate.c
-+++ b/net/mac80211/rate.c
-@@ -385,7 +385,7 @@ static void rate_idx_match_mask(struct i
-                       *rate = alt_rate;
-                       return;
-               }
--      } else {
-+      } else if (!(rate->flags & IEEE80211_TX_RC_VHT_MCS)) {
-               /* handle legacy rates */
-               if (rate_idx_match_legacy_mask(rate, sband->n_bitrates, mask))
-                       return;
diff --git a/package/kernel/mac80211/patches/313-mac80211-minstrel_ht-add-a-small-optimization-to-min.patch b/package/kernel/mac80211/patches/313-mac80211-minstrel_ht-add-a-small-optimization-to-min.patch
deleted file mode 100644 (file)
index ba2ce1e..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-From: Felix Fietkau <nbd@openwrt.org>
-Date: Sat, 15 Nov 2014 22:13:38 +0100
-Subject: [PATCH] mac80211: minstrel_ht: add a small optimization to
- minstrel_aggr_check
-
-Check the queue mapping earlier, skb->queue_mapping is more likely than
-skb->data to still be in d-cache.
-
-Signed-off-by: Felix Fietkau <nbd@openwrt.org>
----
-
---- a/net/mac80211/rc80211_minstrel_ht.c
-+++ b/net/mac80211/rc80211_minstrel_ht.c
-@@ -690,6 +690,9 @@ minstrel_aggr_check(struct ieee80211_sta
-       struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
-       u16 tid;
-+      if (skb_get_queue_mapping(skb) == IEEE80211_AC_VO)
-+              return;
-+
-       if (unlikely(!ieee80211_is_data_qos(hdr->frame_control)))
-               return;
-@@ -700,9 +703,6 @@ minstrel_aggr_check(struct ieee80211_sta
-       if (likely(sta->ampdu_mlme.tid_tx[tid]))
-               return;
--      if (skb_get_queue_mapping(skb) == IEEE80211_AC_VO)
--              return;
--
-       ieee80211_start_tx_ba_session(pubsta, tid, 5000);
- }
diff --git a/package/kernel/mac80211/patches/314-mac80211-minstrel_ht-move-aggregation-check-to-.get_.patch b/package/kernel/mac80211/patches/314-mac80211-minstrel_ht-move-aggregation-check-to-.get_.patch
deleted file mode 100644 (file)
index 38e867f..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-From: Felix Fietkau <nbd@openwrt.org>
-Date: Sat, 15 Nov 2014 22:16:36 +0100
-Subject: [PATCH] mac80211: minstrel_ht: move aggregation check to
- .get_rate()
-
-Preparation for adding a no-skb tx status path
-
-Signed-off-by: Felix Fietkau <nbd@openwrt.org>
----
-
---- a/net/mac80211/rc80211_minstrel_ht.c
-+++ b/net/mac80211/rc80211_minstrel_ht.c
-@@ -782,9 +782,6 @@ minstrel_ht_tx_status(void *priv, struct
-       if (time_after(jiffies, mi->stats_update + (mp->update_interval / 2 * HZ) / 1000)) {
-               update = true;
-               minstrel_ht_update_stats(mp, mi);
--              if (!(info->flags & IEEE80211_TX_CTL_AMPDU) &&
--                  mi->max_prob_rate / MCS_GROUP_RATES != MINSTREL_CCK_GROUP)
--                      minstrel_aggr_check(sta, skb);
-       }
-       if (update)
-@@ -1026,6 +1023,10 @@ minstrel_ht_get_rate(void *priv, struct 
-       if (!msp->is_ht)
-               return mac80211_minstrel.get_rate(priv, sta, &msp->legacy, txrc);
-+      if (!(info->flags & IEEE80211_TX_CTL_AMPDU) &&
-+              mi->max_prob_rate / MCS_GROUP_RATES != MINSTREL_CCK_GROUP)
-+              minstrel_aggr_check(sta, txrc->skb);
-+
-       info->flags |= mi->tx_flags;
-       minstrel_ht_check_cck_shortpreamble(mp, mi, txrc->short_preamble);
diff --git a/package/kernel/mac80211/patches/315-mac80211-add-tx_status_noskb-to-rate_control_ops.patch b/package/kernel/mac80211/patches/315-mac80211-add-tx_status_noskb-to-rate_control_ops.patch
deleted file mode 100644 (file)
index 8a93970..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-From: Felix Fietkau <nbd@openwrt.org>
-Date: Sat, 15 Nov 2014 22:23:44 +0100
-Subject: [PATCH] mac80211: add tx_status_noskb to rate_control_ops
-
-This op works like .tx_status, except it does not need access to the
-skb. This will be used by drivers that cannot match tx status
-information to specific packets.
-
-Signed-off-by: Felix Fietkau <nbd@openwrt.org>
----
-
---- a/include/net/mac80211.h
-+++ b/include/net/mac80211.h
-@@ -4727,6 +4727,10 @@ struct rate_control_ops {
-       void (*free_sta)(void *priv, struct ieee80211_sta *sta,
-                        void *priv_sta);
-+      void (*tx_status_noskb)(void *priv,
-+                              struct ieee80211_supported_band *sband,
-+                              struct ieee80211_sta *sta, void *priv_sta,
-+                              struct ieee80211_tx_info *info);
-       void (*tx_status)(void *priv, struct ieee80211_supported_band *sband,
-                         struct ieee80211_sta *sta, void *priv_sta,
-                         struct sk_buff *skb);
---- a/net/mac80211/rate.h
-+++ b/net/mac80211/rate.h
-@@ -37,11 +37,15 @@ static inline void rate_control_tx_statu
-       struct rate_control_ref *ref = local->rate_ctrl;
-       struct ieee80211_sta *ista = &sta->sta;
-       void *priv_sta = sta->rate_ctrl_priv;
-+      struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
-       if (!ref || !test_sta_flag(sta, WLAN_STA_RATE_CONTROL))
-               return;
--      ref->ops->tx_status(ref->priv, sband, ista, priv_sta, skb);
-+      if (ref->ops->tx_status)
-+              ref->ops->tx_status(ref->priv, sband, ista, priv_sta, skb);
-+      else
-+              ref->ops->tx_status_noskb(ref->priv, sband, ista, priv_sta, info);
- }
diff --git a/package/kernel/mac80211/patches/316-mac80211-minstrel-switch-to-.tx_status_noskb.patch b/package/kernel/mac80211/patches/316-mac80211-minstrel-switch-to-.tx_status_noskb.patch
deleted file mode 100644 (file)
index b32e410..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-From: Felix Fietkau <nbd@openwrt.org>
-Date: Sat, 15 Nov 2014 22:38:07 +0100
-Subject: [PATCH] mac80211: minstrel: switch to .tx_status_noskb
-
-Signed-off-by: Felix Fietkau <nbd@openwrt.org>
----
-
---- a/net/mac80211/rc80211_minstrel.c
-+++ b/net/mac80211/rc80211_minstrel.c
-@@ -223,11 +223,10 @@ minstrel_update_stats(struct minstrel_pr
- static void
- minstrel_tx_status(void *priv, struct ieee80211_supported_band *sband,
-                  struct ieee80211_sta *sta, void *priv_sta,
--                 struct sk_buff *skb)
-+                 struct ieee80211_tx_info *info)
- {
-       struct minstrel_priv *mp = priv;
-       struct minstrel_sta_info *mi = priv_sta;
--      struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
-       struct ieee80211_tx_rate *ar = info->status.rates;
-       int i, ndx;
-       int success;
-@@ -674,7 +673,7 @@ static u32 minstrel_get_expected_through
- const struct rate_control_ops mac80211_minstrel = {
-       .name = "minstrel",
--      .tx_status = minstrel_tx_status,
-+      .tx_status_noskb = minstrel_tx_status,
-       .get_rate = minstrel_get_rate,
-       .rate_init = minstrel_rate_init,
-       .alloc = minstrel_alloc,
diff --git a/package/kernel/mac80211/patches/317-mac80211-minstrel_ht-switch-to-.tx_status_noskb.patch b/package/kernel/mac80211/patches/317-mac80211-minstrel_ht-switch-to-.tx_status_noskb.patch
deleted file mode 100644 (file)
index 6900005..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-From: Felix Fietkau <nbd@openwrt.org>
-Date: Sat, 15 Nov 2014 22:38:21 +0100
-Subject: [PATCH] mac80211: minstrel_ht: switch to .tx_status_noskb
-
-Signed-off-by: Felix Fietkau <nbd@openwrt.org>
----
-
---- a/net/mac80211/rc80211_minstrel_ht.c
-+++ b/net/mac80211/rc80211_minstrel_ht.c
-@@ -709,11 +709,10 @@ minstrel_aggr_check(struct ieee80211_sta
- static void
- minstrel_ht_tx_status(void *priv, struct ieee80211_supported_band *sband,
-                       struct ieee80211_sta *sta, void *priv_sta,
--                      struct sk_buff *skb)
-+                      struct ieee80211_tx_info *info)
- {
-       struct minstrel_ht_sta_priv *msp = priv_sta;
-       struct minstrel_ht_sta *mi = &msp->ht;
--      struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
-       struct ieee80211_tx_rate *ar = info->status.rates;
-       struct minstrel_rate_stats *rate, *rate2;
-       struct minstrel_priv *mp = priv;
-@@ -721,7 +720,8 @@ minstrel_ht_tx_status(void *priv, struct
-       int i;
-       if (!msp->is_ht)
--              return mac80211_minstrel.tx_status(priv, sband, sta, &msp->legacy, skb);
-+              return mac80211_minstrel.tx_status_noskb(priv, sband, sta,
-+                                                       &msp->legacy, info);
-       /* This packet was aggregated but doesn't carry status info */
-       if ((info->flags & IEEE80211_TX_CTL_AMPDU) &&
-@@ -1343,7 +1343,7 @@ static u32 minstrel_ht_get_expected_thro
- static const struct rate_control_ops mac80211_minstrel_ht = {
-       .name = "minstrel_ht",
--      .tx_status = minstrel_ht_tx_status,
-+      .tx_status_noskb = minstrel_ht_tx_status,
-       .get_rate = minstrel_ht_get_rate,
-       .rate_init = minstrel_ht_rate_init,
-       .rate_update = minstrel_ht_rate_update,
diff --git a/package/kernel/mac80211/patches/318-mac80211-add-ieee80211_tx_status_noskb.patch b/package/kernel/mac80211/patches/318-mac80211-add-ieee80211_tx_status_noskb.patch
deleted file mode 100644 (file)
index 18d3905..0000000
+++ /dev/null
@@ -1,219 +0,0 @@
-From: Felix Fietkau <nbd@openwrt.org>
-Date: Sat, 15 Nov 2014 23:50:27 +0100
-Subject: [PATCH] mac80211: add ieee80211_tx_status_noskb
-
-This can be used by drivers that cannot reliably map tx status
-information onto specific skbs.
-
-Signed-off-by: Felix Fietkau <nbd@openwrt.org>
----
-
---- a/include/net/mac80211.h
-+++ b/include/net/mac80211.h
-@@ -3517,6 +3517,28 @@ void ieee80211_tx_status(struct ieee8021
-                        struct sk_buff *skb);
- /**
-+ * ieee80211_tx_status_noskb - transmit status callback without skb
-+ *
-+ * This function can be used as a replacement for ieee80211_tx_status
-+ * in drivers that cannot reliably map tx status information back to
-+ * specific skbs.
-+ *
-+ * 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. Must not run concurrently with
-+ * ieee80211_rx() or ieee80211_rx_ni().
-+ *
-+ * @hw: the hardware the frame was transmitted by
-+ * @sta: the receiver station to which this packet is sent
-+ *    (NULL for multicast packets)
-+ * @info: tx status information
-+ */
-+void ieee80211_tx_status_noskb(struct ieee80211_hw *hw,
-+                             struct ieee80211_sta *sta,
-+                             struct ieee80211_tx_info *info);
-+
-+/**
-  * ieee80211_tx_status_ni - transmit status callback (in process context)
-  *
-  * Like ieee80211_tx_status() but can be called in process context.
---- a/net/mac80211/rate.h
-+++ b/net/mac80211/rate.h
-@@ -49,6 +49,23 @@ static inline void rate_control_tx_statu
- }
-+static inline void
-+rate_control_tx_status_noskb(struct ieee80211_local *local,
-+                           struct ieee80211_supported_band *sband,
-+                           struct sta_info *sta,
-+                           struct ieee80211_tx_info *info)
-+{
-+      struct rate_control_ref *ref = local->rate_ctrl;
-+      struct ieee80211_sta *ista = &sta->sta;
-+      void *priv_sta = sta->rate_ctrl_priv;
-+
-+      if (!ref || !test_sta_flag(sta, WLAN_STA_RATE_CONTROL))
-+              return;
-+
-+      ref->ops->tx_status_noskb(ref->priv, sband, ista, priv_sta, info);
-+}
-+
-+
- static inline void rate_control_rate_init(struct sta_info *sta)
- {
-       struct ieee80211_local *local = sta->sdata->local;
---- a/net/mac80211/status.c
-+++ b/net/mac80211/status.c
-@@ -541,10 +541,9 @@ static void ieee80211_tx_latency_end_msr
- #define STA_LOST_TDLS_PKT_THRESHOLD   10
- #define STA_LOST_TDLS_PKT_TIME                (10*HZ) /* 10secs since last ACK */
--static void ieee80211_lost_packet(struct sta_info *sta, struct sk_buff *skb)
-+static void ieee80211_lost_packet(struct sta_info *sta,
-+                                struct ieee80211_tx_info *info)
- {
--      struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
--
-       /* This packet was aggregated but doesn't carry status info */
-       if ((info->flags & IEEE80211_TX_CTL_AMPDU) &&
-           !(info->flags & IEEE80211_TX_STAT_AMPDU))
-@@ -571,24 +570,13 @@ static void ieee80211_lost_packet(struct
-       sta->lost_packets = 0;
- }
--void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
-+static int ieee80211_tx_get_rates(struct ieee80211_hw *hw,
-+                                struct ieee80211_tx_info *info,
-+                                int *retry_count)
- {
--      struct sk_buff *skb2;
--      struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
--      struct ieee80211_local *local = hw_to_local(hw);
--      struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
--      __le16 fc;
--      struct ieee80211_supported_band *sband;
--      struct ieee80211_sub_if_data *sdata;
--      struct net_device *prev_dev = NULL;
--      struct sta_info *sta, *tmp;
--      int retry_count = -1, i;
-       int rates_idx = -1;
--      bool send_to_cooked;
--      bool acked;
--      struct ieee80211_bar *bar;
--      int rtap_len;
--      int shift = 0;
-+      int count = -1;
-+      int i;
-       for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) {
-               if ((info->flags & IEEE80211_TX_CTL_AMPDU) &&
-@@ -606,12 +594,94 @@ void ieee80211_tx_status(struct ieee8021
-                       break;
-               }
--              retry_count += info->status.rates[i].count;
-+              count += info->status.rates[i].count;
-       }
-       rates_idx = i - 1;
--      if (retry_count < 0)
--              retry_count = 0;
-+      if (count < 0)
-+              count = 0;
-+
-+      *retry_count = count;
-+      return rates_idx;
-+}
-+
-+void ieee80211_tx_status_noskb(struct ieee80211_hw *hw,
-+                             struct ieee80211_sta *pubsta,
-+                             struct ieee80211_tx_info *info)
-+{
-+      struct ieee80211_local *local = hw_to_local(hw);
-+      struct ieee80211_supported_band *sband;
-+      int retry_count;
-+      int rates_idx;
-+      bool acked;
-+
-+      rates_idx = ieee80211_tx_get_rates(hw, info, &retry_count);
-+
-+      sband = hw->wiphy->bands[info->band];
-+
-+      acked = !!(info->flags & IEEE80211_TX_STAT_ACK);
-+      if (pubsta) {
-+              struct sta_info *sta;
-+
-+              sta = container_of(pubsta, struct sta_info, sta);
-+
-+              if (info->flags & IEEE80211_TX_STATUS_EOSP)
-+                      clear_sta_flag(sta, WLAN_STA_SP);
-+
-+              if (!acked)
-+                      sta->tx_retry_failed++;
-+              sta->tx_retry_count += retry_count;
-+
-+              if (acked) {
-+                      sta->last_rx = jiffies;
-+
-+                      if (sta->lost_packets)
-+                              sta->lost_packets = 0;
-+
-+                      /* Track when last TDLS packet was ACKed */
-+                      if (test_sta_flag(sta, WLAN_STA_TDLS_PEER_AUTH))
-+                              sta->last_tdls_pkt_time = jiffies;
-+              } else {
-+                      ieee80211_lost_packet(sta, info);
-+              }
-+
-+              rate_control_tx_status_noskb(local, sband, sta, info);
-+      }
-+
-+      if (acked) {
-+                  local->dot11TransmittedFrameCount++;
-+                  if (!pubsta)
-+                          local->dot11MulticastTransmittedFrameCount++;
-+                  if (retry_count > 0)
-+                          local->dot11RetryCount++;
-+                  if (retry_count > 1)
-+                          local->dot11MultipleRetryCount++;
-+      } else {
-+              local->dot11FailedCount++;
-+      }
-+}
-+EXPORT_SYMBOL(ieee80211_tx_status_noskb);
-+
-+void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
-+{
-+      struct sk_buff *skb2;
-+      struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
-+      struct ieee80211_local *local = hw_to_local(hw);
-+      struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
-+      __le16 fc;
-+      struct ieee80211_supported_band *sband;
-+      struct ieee80211_sub_if_data *sdata;
-+      struct net_device *prev_dev = NULL;
-+      struct sta_info *sta, *tmp;
-+      int retry_count;
-+      int rates_idx;
-+      bool send_to_cooked;
-+      bool acked;
-+      struct ieee80211_bar *bar;
-+      int rtap_len;
-+      int shift = 0;
-+
-+      rates_idx = ieee80211_tx_get_rates(hw, info, &retry_count);
-       rcu_read_lock();
-@@ -716,7 +786,7 @@ void ieee80211_tx_status(struct ieee8021
-                               if (test_sta_flag(sta, WLAN_STA_TDLS_PEER_AUTH))
-                                       sta->last_tdls_pkt_time = jiffies;
-                       } else {
--                              ieee80211_lost_packet(sta, skb);
-+                              ieee80211_lost_packet(sta, info);
-                       }
-               }
diff --git a/package/kernel/mac80211/patches/319-mac80211-minstrel_ht-fix-a-crash-in-rate-sorting.patch b/package/kernel/mac80211/patches/319-mac80211-minstrel_ht-fix-a-crash-in-rate-sorting.patch
deleted file mode 100644 (file)
index 784a973..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-From: Felix Fietkau <nbd@openwrt.org>
-Date: Tue, 18 Nov 2014 21:43:25 +0100
-Subject: [PATCH] mac80211: minstrel_ht: fix a crash in rate sorting
-
-The commit 5935839ad73583781b8bbe8d91412f6826e218a4
-"mac80211: improve minstrel_ht rate sorting by throughput & probability"
-
-introduced a crash on rate sorting that occurs when the rate added to
-the sorting array is faster than all the previous rates. Due to an
-off-by-one error, it reads the rate index from tp_list[-1], which
-contains uninitialized stack garbage, and then uses the resulting index
-for accessing the group rate stats, leading to a crash if the garbage
-value is big enough.
-
-Cc: Thomas Huehn <thomas@net.t-labs.tu-berlin.de>
-Reported-by: Jouni Malinen <j@w1.fi>
-Signed-off-by: Felix Fietkau <nbd@openwrt.org>
----
-
---- a/net/mac80211/rc80211_minstrel_ht.c
-+++ b/net/mac80211/rc80211_minstrel_ht.c
-@@ -394,19 +394,16 @@ minstrel_ht_sort_best_tp_rates(struct mi
-       cur_thr = mi->groups[cur_group].rates[cur_idx].cur_tp;
-       cur_prob = mi->groups[cur_group].rates[cur_idx].probability;
--      tmp_group = tp_list[j - 1] / MCS_GROUP_RATES;
--      tmp_idx = tp_list[j - 1] % MCS_GROUP_RATES;
--      tmp_thr = mi->groups[tmp_group].rates[tmp_idx].cur_tp;
--      tmp_prob = mi->groups[tmp_group].rates[tmp_idx].probability;
--
--      while (j > 0 && (cur_thr > tmp_thr ||
--            (cur_thr == tmp_thr && cur_prob > tmp_prob))) {
--              j--;
-+      do {
-               tmp_group = tp_list[j - 1] / MCS_GROUP_RATES;
-               tmp_idx = tp_list[j - 1] % MCS_GROUP_RATES;
-               tmp_thr = mi->groups[tmp_group].rates[tmp_idx].cur_tp;
-               tmp_prob = mi->groups[tmp_group].rates[tmp_idx].probability;
--      }
-+              if (cur_thr < tmp_thr ||
-+                  (cur_thr == tmp_thr && cur_prob <= tmp_prob))
-+                      break;
-+              j--;
-+      } while (j > 0);
-       if (j < MAX_THR_RATES - 1) {
-               memmove(&tp_list[j + 1], &tp_list[j], (sizeof(*tp_list) *
diff --git a/package/kernel/mac80211/patches/320-mac80211-notify-drivers-on-sta-rate-table-changes.patch b/package/kernel/mac80211/patches/320-mac80211-notify-drivers-on-sta-rate-table-changes.patch
deleted file mode 100644 (file)
index 2ae0729..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-From: Johannes Berg <johannes.berg@intel.com>
-Date: Tue, 18 Nov 2014 23:26:40 +0100
-Subject: [PATCH] mac80211: notify drivers on sta rate table changes
-
-This allows drivers with a firmware or chip-based rate lookup table to
-use the most recent default rate selection without having to get it from
-per-packet data or explicit ieee80211_get_tx_rate calls
-
-Signed-off-by: Felix Fietkau <nbd@openwrt.org>
----
-
---- a/include/net/mac80211.h
-+++ b/include/net/mac80211.h
-@@ -2631,6 +2631,9 @@ enum ieee80211_reconfig_type {
-  *    uses hardware rate control (%IEEE80211_HW_HAS_RATE_CONTROL) since
-  *    otherwise the rate control algorithm is notified directly.
-  *    Must be atomic.
-+ * @sta_rate_tbl_update: Notifies the driver that the rate table changed. This
-+ *    is only used if the configured rate control algorithm actually uses
-+ *    the new rate table API, and is therefore optional. Must be atomic.
-  *
-  * @conf_tx: Configure TX queue parameters (EDCF (aifs, cw_min, cw_max),
-  *    bursting) for a hardware TX queue.
-@@ -2972,6 +2975,9 @@ struct ieee80211_ops {
-                             struct ieee80211_vif *vif,
-                             struct ieee80211_sta *sta,
-                             u32 changed);
-+      void (*sta_rate_tbl_update)(struct ieee80211_hw *hw,
-+                                  struct ieee80211_vif *vif,
-+                                  struct ieee80211_sta *sta);
-       int (*conf_tx)(struct ieee80211_hw *hw,
-                      struct ieee80211_vif *vif, u16 ac,
-                      const struct ieee80211_tx_queue_params *params);
---- a/net/mac80211/driver-ops.h
-+++ b/net/mac80211/driver-ops.h
-@@ -621,6 +621,21 @@ static inline void drv_sta_rc_update(str
-       trace_drv_return_void(local);
- }
-+static inline void drv_sta_rate_tbl_update(struct ieee80211_local *local,
-+                                         struct ieee80211_sub_if_data *sdata,
-+                                         struct ieee80211_sta *sta)
-+{
-+      sdata = get_bss_sdata(sdata);
-+      if (!check_sdata_in_driver(sdata))
-+              return;
-+
-+      trace_drv_sta_rate_tbl_update(local, sdata, sta);
-+      if (local->ops->sta_rate_tbl_update)
-+              local->ops->sta_rate_tbl_update(&local->hw, &sdata->vif, sta);
-+
-+      trace_drv_return_void(local);
-+}
-+
- static inline int drv_conf_tx(struct ieee80211_local *local,
-                             struct ieee80211_sub_if_data *sdata, u16 ac,
-                             const struct ieee80211_tx_queue_params *params)
---- a/net/mac80211/rate.c
-+++ b/net/mac80211/rate.c
-@@ -696,6 +696,7 @@ int rate_control_set_rates(struct ieee80
-                          struct ieee80211_sta *pubsta,
-                          struct ieee80211_sta_rates *rates)
- {
-+      struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
-       struct ieee80211_sta_rates *old;
-       /*
-@@ -709,6 +710,8 @@ int rate_control_set_rates(struct ieee80
-       if (old)
-               kfree_rcu(old, rcu_head);
-+      drv_sta_rate_tbl_update(hw_to_local(hw), sta->sdata, pubsta);
-+
-       return 0;
- }
- EXPORT_SYMBOL(rate_control_set_rates);
---- a/net/mac80211/trace.h
-+++ b/net/mac80211/trace.h
-@@ -826,6 +826,13 @@ DEFINE_EVENT(sta_event, drv_sta_pre_rcu_
-       TP_ARGS(local, sdata, sta)
- );
-+DEFINE_EVENT(sta_event, drv_sta_rate_tbl_update,
-+      TP_PROTO(struct ieee80211_local *local,
-+               struct ieee80211_sub_if_data *sdata,
-+               struct ieee80211_sta *sta),
-+      TP_ARGS(local, sdata, sta)
-+);
-+
- TRACE_EVENT(drv_conf_tx,
-       TP_PROTO(struct ieee80211_local *local,
-                struct ieee80211_sub_if_data *sdata,
diff --git a/package/kernel/mac80211/patches/321-mac80211-add-an-intermediate-software-queue-implemen.patch b/package/kernel/mac80211/patches/321-mac80211-add-an-intermediate-software-queue-implemen.patch
deleted file mode 100644 (file)
index a9e95ff..0000000
+++ /dev/null
@@ -1,498 +0,0 @@
-From: Felix Fietkau <nbd@openwrt.org>
-Date: Tue, 18 Nov 2014 23:58:51 +0100
-Subject: [PATCH] mac80211: add an intermediate software queue implementation
-
-This allows drivers to request per-vif and per-sta-tid queues from which
-they can pull frames. This makes it easier to keep the hardware queues
-short, and to improve fairness between clients and vifs.
-
-The task of scheduling packet transmission is left up to the driver -
-queueing is controlled by mac80211. Drivers can only dequeue packets by
-calling ieee80211_tx_dequeue. This makes it possible to add active queue
-management later without changing drivers using this code.
-
-This can also be used as a starting point to implement A-MSDU
-aggregation in a way that does not add artificially induced latency.
-
-Signed-off-by: Felix Fietkau <nbd@openwrt.org>
----
-
---- a/include/net/mac80211.h
-+++ b/include/net/mac80211.h
-@@ -1192,6 +1192,8 @@ struct ieee80211_vif {
-       u8 cab_queue;
-       u8 hw_queue[IEEE80211_NUM_ACS];
-+      struct ieee80211_txq *txq;
-+
-       struct ieee80211_chanctx_conf __rcu *chanctx_conf;
-       u32 driver_flags;
-@@ -1448,6 +1450,8 @@ struct ieee80211_sta {
-       bool tdls;
-       bool tdls_initiator;
-+      struct ieee80211_txq *txq[IEEE80211_NUM_TIDS];
-+
-       /* must be last */
-       u8 drv_priv[0] __aligned(sizeof(void *));
- };
-@@ -1476,6 +1480,27 @@ struct ieee80211_tx_control {
- };
- /**
-+ * struct ieee80211_txq - Software intermediate tx queue
-+ *
-+ * @vif: &struct ieee80211_vif pointer from the add_interface callback.
-+ * @sta: station table entry, may be NULL for per-vif queue
-+ * @tid: the TID for this queue (unset for per-vif queue)
-+ * @ac: the AC for this queue
-+ *
-+ * The driver can obtain packets from this queue by calling
-+ * ieee80211_tx_dequeue().
-+ */
-+struct ieee80211_txq {
-+      struct ieee80211_vif *vif;
-+      struct ieee80211_sta *sta;
-+      u8 tid;
-+      u8 ac;
-+
-+      /* must be last */
-+      u8 drv_priv[0] __aligned(sizeof(void *));
-+};
-+
-+/**
-  * enum ieee80211_hw_flags - hardware flags
-  *
-  * These flags are used to indicate hardware capabilities to
-@@ -1698,6 +1723,8 @@ enum ieee80211_hw_flags {
-  *    within &struct ieee80211_sta.
-  * @chanctx_data_size: size (in bytes) of the drv_priv data area
-  *    within &struct ieee80211_chanctx_conf.
-+ * @txq_data_size: size (in bytes) of the drv_priv data area
-+ *    within @struct ieee80211_txq.
-  *
-  * @max_rates: maximum number of alternate rate retry stages the hw
-  *    can handle.
-@@ -1746,6 +1773,9 @@ enum ieee80211_hw_flags {
-  * @n_cipher_schemes: a size of an array of cipher schemes definitions.
-  * @cipher_schemes: a pointer to an array of cipher scheme definitions
-  *    supported by HW.
-+ *
-+ * @txq_ac_max_pending: maximum number of frames per AC pending in all txq
-+ *    entries for a vif.
-  */
- struct ieee80211_hw {
-       struct ieee80211_conf conf;
-@@ -1758,6 +1788,7 @@ struct ieee80211_hw {
-       int vif_data_size;
-       int sta_data_size;
-       int chanctx_data_size;
-+      int txq_data_size;
-       u16 queues;
-       u16 max_listen_interval;
-       s8 max_signal;
-@@ -1774,6 +1805,7 @@ struct ieee80211_hw {
-       u8 uapsd_max_sp_len;
-       u8 n_cipher_schemes;
-       const struct ieee80211_cipher_scheme *cipher_schemes;
-+      int txq_ac_max_pending;
- };
- /**
-@@ -2881,6 +2913,8 @@ enum ieee80211_reconfig_type {
-  *
-  * @get_txpower: get current maximum tx power (in dBm) based on configuration
-  *    and hardware limits.
-+ *
-+ * @wake_tx_queue: Called when new packets have been added to the queue.
-  */
- struct ieee80211_ops {
-       void (*tx)(struct ieee80211_hw *hw,
-@@ -3095,6 +3129,9 @@ struct ieee80211_ops {
-       u32 (*get_expected_throughput)(struct ieee80211_sta *sta);
-       int (*get_txpower)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
-                          int *dbm);
-+
-+      void (*wake_tx_queue)(struct ieee80211_hw *hw,
-+                            struct ieee80211_txq *txq);
- };
- /**
-@@ -5038,4 +5075,17 @@ void ieee80211_tdls_oper_request(struct 
-  */
- size_t ieee80211_ie_split(const u8 *ies, size_t ielen,
-                         const u8 *ids, int n_ids, size_t offset);
-+
-+/**
-+ * ieee80211_tx_dequeue - dequeue a packet from a software tx queue
-+ *
-+ * @hw: pointer as obtained from ieee80211_alloc_hw()
-+ * @txq: pointer obtained from .add_tx_queue() call
-+ *
-+ * Returns 0 if successful, -EAGAIN if no frame was available.
-+ */
-+int ieee80211_tx_dequeue(struct ieee80211_hw *hw, struct ieee80211_txq *txq,
-+                       struct sk_buff **skb);
-+
-+
- #endif /* MAC80211_H */
---- a/net/mac80211/driver-ops.h
-+++ b/net/mac80211/driver-ops.h
-@@ -1311,4 +1311,21 @@ static inline int drv_get_txpower(struct
-       return ret;
- }
-+static inline void drv_wake_tx_queue(struct ieee80211_local *local,
-+                                   struct txq_info *txq)
-+{
-+      struct ieee80211_sub_if_data *sdata = vif_to_sdata(txq->txq.vif);
-+
-+      if (!check_sdata_in_driver(sdata))
-+              return;
-+
-+      if (txq->txq.sta)
-+              trace_drv_wake_sta_tx_queue(local, sdata, txq->txq.sta,
-+                                          txq->txq.tid);
-+      else
-+              trace_drv_wake_vif_tx_queue(local, sdata);
-+
-+      local->ops->wake_tx_queue(&local->hw, &txq->txq);
-+}
-+
- #endif /* __MAC80211_DRIVER_OPS */
---- a/net/mac80211/ieee80211_i.h
-+++ b/net/mac80211/ieee80211_i.h
-@@ -793,6 +793,13 @@ struct mac80211_qos_map {
-       struct rcu_head rcu_head;
- };
-+struct txq_info {
-+      struct sk_buff_head queue;
-+
-+      /* keep last! */
-+      struct ieee80211_txq txq;
-+};
-+
- struct ieee80211_sub_if_data {
-       struct list_head list;
-@@ -837,6 +844,8 @@ struct ieee80211_sub_if_data {
-       bool control_port_no_encrypt;
-       int encrypt_headroom;
-+      struct txq_info *txq;
-+      atomic_t txq_len[IEEE80211_NUM_ACS];
-       struct ieee80211_tx_queue_params tx_conf[IEEE80211_NUM_ACS];
-       struct mac80211_qos_map __rcu *qos_map;
-@@ -1868,6 +1877,11 @@ void ieee80211_add_pending_skbs(struct i
-                               struct sk_buff_head *skbs);
- void ieee80211_flush_queues(struct ieee80211_local *local,
-                           struct ieee80211_sub_if_data *sdata);
-+void ieee80211_init_tx_queue(struct ieee80211_sub_if_data *sdata,
-+                           struct sta_info *sta,
-+                           struct txq_info *txq, int tid);
-+void ieee80211_flush_tx_queue(struct ieee80211_local *local,
-+                            struct ieee80211_txq *txq);
- void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
-                        u16 transaction, u16 auth_alg, u16 status,
---- a/net/mac80211/iface.c
-+++ b/net/mac80211/iface.c
-@@ -967,6 +967,9 @@ static void ieee80211_do_stop(struct iee
-       }
-       spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
-+      if (sdata->vif.txq)
-+              ieee80211_flush_tx_queue(local, sdata->vif.txq);
-+
-       if (local->open_count == 0)
-               ieee80211_clear_tx_pending(local);
-@@ -1773,6 +1776,13 @@ int ieee80211_if_add(struct ieee80211_lo
-       /* setup type-dependent data */
-       ieee80211_setup_sdata(sdata, type);
-+      if (local->ops->wake_tx_queue) {
-+              sdata->txq = kzalloc(sizeof(*sdata->txq) +
-+                                   local->hw.txq_data_size, GFP_KERNEL);
-+              if (sdata->txq)
-+                      ieee80211_init_tx_queue(sdata, NULL, sdata->txq, 0);
-+      }
-+
-       if (ndev) {
-               if (params) {
-                       ndev->ieee80211_ptr->use_4addr = params->use_4addr;
---- a/net/mac80211/main.c
-+++ b/net/mac80211/main.c
-@@ -1004,6 +1004,9 @@ int ieee80211_register_hw(struct ieee802
-       local->dynamic_ps_forced_timeout = -1;
-+      if (!local->hw.txq_ac_max_pending)
-+              local->hw.txq_ac_max_pending = 64;
-+
-       result = ieee80211_wep_init(local);
-       if (result < 0)
-               wiphy_debug(local->hw.wiphy, "Failed to initialize wep: %d\n",
---- a/net/mac80211/sta_info.c
-+++ b/net/mac80211/sta_info.c
-@@ -119,6 +119,11 @@ static void __cleanup_single_sta(struct 
-               sta_info_recalc_tim(sta);
-       }
-+      if (sta->txq) {
-+              for (i = 0; i < IEEE80211_NUM_TIDS; i++)
-+                      ieee80211_flush_tx_queue(local, sta->sta.txq[i]);
-+      }
-+
-       for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
-               local->total_ps_buffered -= skb_queue_len(&sta->ps_tx_buf[ac]);
-               ieee80211_purge_tx_queue(&local->hw, &sta->ps_tx_buf[ac]);
-@@ -241,6 +246,8 @@ void sta_info_free(struct ieee80211_loca
-               kfree(sta->tx_lat);
-       }
-+      kfree(sta->txq);
-+
-       sta_dbg(sta->sdata, "Destroyed STA %pM\n", sta->sta.addr);
-       kfree(rcu_dereference_raw(sta->sta.rates));
-@@ -294,12 +301,13 @@ struct sta_info *sta_info_alloc(struct i
-                               const u8 *addr, gfp_t gfp)
- {
-       struct ieee80211_local *local = sdata->local;
-+      struct ieee80211_hw *hw = &local->hw;
-       struct sta_info *sta;
-       struct timespec uptime;
-       struct ieee80211_tx_latency_bin_ranges *tx_latency;
-       int i;
--      sta = kzalloc(sizeof(*sta) + local->hw.sta_data_size, gfp);
-+      sta = kzalloc(sizeof(*sta) + hw->sta_data_size, gfp);
-       if (!sta)
-               return NULL;
-@@ -357,6 +365,20 @@ struct sta_info *sta_info_alloc(struct i
-       for (i = 0; i < ARRAY_SIZE(sta->chain_signal_avg); i++)
-               ewma_init(&sta->chain_signal_avg[i], 1024, 8);
-+      if (local->ops->wake_tx_queue) {
-+              int size = sizeof(struct txq_info) +
-+                         ALIGN(hw->txq_data_size, sizeof(void *));
-+
-+              sta->txq = kcalloc(IEEE80211_NUM_TIDS, size, gfp);
-+              if (!sta->txq)
-+                      goto free;
-+
-+              for (i = 0; i < IEEE80211_NUM_TIDS; i++) {
-+                      struct txq_info *txq = sta->txq + i * size;
-+                      ieee80211_init_tx_queue(sdata, sta, txq, i);
-+              }
-+      }
-+
-       if (sta_prepare_rate_control(local, sta, gfp))
-               goto free;
-@@ -380,7 +402,7 @@ struct sta_info *sta_info_alloc(struct i
-       if (sdata->vif.type == NL80211_IFTYPE_AP ||
-           sdata->vif.type == NL80211_IFTYPE_AP_VLAN) {
-               struct ieee80211_supported_band *sband =
--                      local->hw.wiphy->bands[ieee80211_get_sdata_band(sdata)];
-+                      hw->wiphy->bands[ieee80211_get_sdata_band(sdata)];
-               u8 smps = (sband->ht_cap.cap & IEEE80211_HT_CAP_SM_PS) >>
-                               IEEE80211_HT_CAP_SM_PS_SHIFT;
-               /*
---- a/net/mac80211/sta_info.h
-+++ b/net/mac80211/sta_info.h
-@@ -371,6 +371,7 @@ struct sta_info {
-       struct sk_buff_head ps_tx_buf[IEEE80211_NUM_ACS];
-       struct sk_buff_head tx_filtered[IEEE80211_NUM_ACS];
-       unsigned long driver_buffered_tids;
-+      void *txq;
-       /* Updated from RX path only, no locking requirements */
-       unsigned long rx_packets;
---- a/net/mac80211/trace.h
-+++ b/net/mac80211/trace.h
-@@ -2201,6 +2201,40 @@ TRACE_EVENT(drv_get_txpower,
-       )
- );
-+DEFINE_EVENT(local_sdata_evt, drv_wake_vif_tx_queue,
-+      TP_PROTO(struct ieee80211_local *local,
-+               struct ieee80211_sub_if_data *sdata),
-+      TP_ARGS(local, sdata)
-+);
-+
-+TRACE_EVENT(drv_wake_sta_tx_queue,
-+      TP_PROTO(struct ieee80211_local *local,
-+               struct ieee80211_sub_if_data *sdata,
-+               struct ieee80211_sta *sta,
-+               u8 tid),
-+
-+      TP_ARGS(local, sdata, sta, tid),
-+
-+      TP_STRUCT__entry(
-+              LOCAL_ENTRY
-+              VIF_ENTRY
-+              STA_ENTRY
-+              __field(u8, tid)
-+      ),
-+
-+      TP_fast_assign(
-+              LOCAL_ASSIGN;
-+              VIF_ASSIGN;
-+              STA_ASSIGN;
-+              __entry->tid = tid;
-+      ),
-+
-+      TP_printk(
-+              LOCAL_PR_FMT  VIF_PR_FMT  STA_PR_FMT " tid: 0x%x",
-+              LOCAL_PR_ARG, VIF_PR_ARG, STA_PR_ARG, __entry->tid
-+      )
-+);
-+
- #ifdef CPTCFG_MAC80211_MESSAGE_TRACING
- #undef TRACE_SYSTEM
---- a/net/mac80211/tx.c
-+++ b/net/mac80211/tx.c
-@@ -1198,13 +1198,75 @@ ieee80211_tx_prepare(struct ieee80211_su
-       return TX_CONTINUE;
- }
-+static void ieee80211_drv_tx(struct ieee80211_local *local,
-+                           struct ieee80211_vif *vif,
-+                           struct ieee80211_sta *pubsta,
-+                           struct sk_buff *skb)
-+{
-+      struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
-+      struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
-+      struct ieee80211_tx_control control = {
-+              .sta = pubsta
-+      };
-+      struct ieee80211_txq *pubtxq = NULL;
-+      struct txq_info *txq;
-+      u8 ac;
-+
-+      if (ieee80211_is_mgmt(hdr->frame_control) ||
-+          ieee80211_is_ctl(hdr->frame_control))
-+              goto tx_normal;
-+
-+      if (pubsta) {
-+              u8 tid = skb->priority & IEEE80211_QOS_CTL_TID_MASK;
-+              pubtxq = pubsta->txq[tid];
-+      } else if (vif) {
-+              pubtxq = vif->txq;
-+      }
-+
-+      if (!pubtxq)
-+              goto tx_normal;
-+
-+      ac = pubtxq->ac;
-+      txq = container_of(pubtxq, struct txq_info, txq);
-+      atomic_inc(&sdata->txq_len[ac]);
-+      if (atomic_read(&sdata->txq_len[ac]) >= local->hw.txq_ac_max_pending)
-+              netif_stop_subqueue(sdata->dev, ac);
-+
-+      skb_queue_tail(&txq->queue, skb);
-+      drv_wake_tx_queue(local, txq);
-+
-+      return;
-+
-+tx_normal:
-+      drv_tx(local, &control, skb);
-+}
-+
-+int ieee80211_tx_dequeue(struct ieee80211_hw *hw, struct ieee80211_txq *pubtxq,
-+                       struct sk_buff **dest)
-+{
-+      struct ieee80211_local *local = hw_to_local(hw);
-+      struct ieee80211_sub_if_data *sdata = vif_to_sdata(pubtxq->vif);
-+      struct txq_info *txq = container_of(pubtxq, struct txq_info, txq);
-+      u8 ac = pubtxq->ac;
-+
-+      *dest = skb_dequeue(&txq->queue);
-+      if (!*dest)
-+              return -EAGAIN;
-+
-+      atomic_dec(&sdata->txq_len[ac]);
-+      if (__netif_subqueue_stopped(sdata->dev, ac))
-+              ieee80211_propagate_queue_wake(local, sdata->vif.hw_queue[ac]);
-+
-+      return 0;
-+}
-+EXPORT_SYMBOL(ieee80211_tx_dequeue);
-+
- static bool ieee80211_tx_frags(struct ieee80211_local *local,
-                              struct ieee80211_vif *vif,
-                              struct ieee80211_sta *sta,
-                              struct sk_buff_head *skbs,
-                              bool txpending)
- {
--      struct ieee80211_tx_control control;
-       struct sk_buff *skb, *tmp;
-       unsigned long flags;
-@@ -1262,10 +1324,9 @@ static bool ieee80211_tx_frags(struct ie
-               spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
-               info->control.vif = vif;
--              control.sta = sta;
-               __skb_unlink(skb, skbs);
--              drv_tx(local, &control, skb);
-+              ieee80211_drv_tx(local, vif, sta, skb);
-       }
-       return true;
---- a/net/mac80211/util.c
-+++ b/net/mac80211/util.c
-@@ -308,6 +308,11 @@ void ieee80211_propagate_queue_wake(stru
-               for (ac = 0; ac < n_acs; ac++) {
-                       int ac_queue = sdata->vif.hw_queue[ac];
-+                      if (local->ops->wake_tx_queue &&
-+                          (atomic_read(&sdata->txq_len[ac]) >
-+                           local->hw.txq_ac_max_pending))
-+                              continue;
-+
-                       if (ac_queue == queue ||
-                           (sdata->vif.cab_queue == queue &&
-                            local->queue_stop_reasons[ac_queue] == 0 &&
-@@ -3182,3 +3187,33 @@ u8 *ieee80211_add_wmm_info_ie(u8 *buf, u
-       return buf;
- }
-+
-+void ieee80211_init_tx_queue(struct ieee80211_sub_if_data *sdata,
-+                           struct sta_info *sta,
-+                           struct txq_info *txq, int tid)
-+{
-+      skb_queue_head_init(&txq->queue);
-+      txq->txq.vif = &sdata->vif;
-+
-+      if (sta) {
-+              txq->txq.sta = &sta->sta;
-+              sta->sta.txq[tid] = &txq->txq;
-+              txq->txq.ac = ieee802_1d_to_ac[tid & 7];
-+      } else {
-+              sdata->vif.txq = &txq->txq;
-+              txq->txq.ac = IEEE80211_AC_BE;
-+      }
-+}
-+
-+void ieee80211_flush_tx_queue(struct ieee80211_local *local,
-+                            struct ieee80211_txq *pubtxq)
-+{
-+      struct txq_info *txq = container_of(pubtxq, struct txq_info, txq);
-+      struct ieee80211_sub_if_data *sdata = vif_to_sdata(pubtxq->vif);
-+      struct sk_buff *skb;
-+
-+      while ((skb = skb_dequeue(&txq->queue)) != NULL) {
-+              atomic_dec(&sdata->txq_len[pubtxq->ac]);
-+              ieee80211_free_txskb(&local->hw, skb);
-+      }
-+}
diff --git a/package/kernel/mac80211/patches/322-mac80211-add-more-missing-checks-for-VHT-tx-rates.patch b/package/kernel/mac80211/patches/322-mac80211-add-more-missing-checks-for-VHT-tx-rates.patch
deleted file mode 100644 (file)
index 4d1465c..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-From: Felix Fietkau <nbd@openwrt.org>
-Date: Fri, 21 Nov 2014 23:27:33 +0100
-Subject: [PATCH] mac80211: add more missing checks for VHT tx rates
-
-Fixes a crash on attempting to calculate the frame duration for a VHT
-packet (which needs to be handled by hw/driver instead).
-
-Reported-by: Jouni Malinen <j@w1.fi>
-Signed-off-by: Felix Fietkau <nbd@openwrt.org>
----
-
---- a/net/mac80211/rate.c
-+++ b/net/mac80211/rate.c
-@@ -446,7 +446,8 @@ static void rate_fixup_ratelist(struct i
-        *
-        * XXX: Should this check all retry rates?
-        */
--      if (!(rates[0].flags & IEEE80211_TX_RC_MCS)) {
-+      if (!(rates[0].flags &
-+            (IEEE80211_TX_RC_MCS | IEEE80211_TX_RC_VHT_MCS))) {
-               u32 basic_rates = vif->bss_conf.basic_rates;
-               s8 baserate = basic_rates ? ffs(basic_rates) - 1 : 0;
---- a/net/mac80211/tx.c
-+++ b/net/mac80211/tx.c
-@@ -60,7 +60,7 @@ static __le16 ieee80211_duration(struct 
-       rcu_read_unlock();
-       /* assume HW handles this */
--      if (tx->rate.flags & IEEE80211_TX_RC_MCS)
-+      if (tx->rate.flags & (IEEE80211_TX_RC_MCS | IEEE80211_TX_RC_VHT_MCS))
-               return 0;
-       /* uh huh? */
diff --git a/package/kernel/mac80211/patches/323-mac80211-copy-chandef-from-AP-vif-to-VLANs.patch b/package/kernel/mac80211/patches/323-mac80211-copy-chandef-from-AP-vif-to-VLANs.patch
deleted file mode 100644 (file)
index fca0c16..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-From: Felix Fietkau <nbd@openwrt.org>
-Date: Mon, 24 Nov 2014 18:09:03 +0100
-Subject: [PATCH] mac80211: copy chandef from AP vif to VLANs
-
-Fixes a crash in nl80211_send_chandef, introduced in
-
-commit c12bc4885f4b3bab0ed779c69d5d7e3223fa5003
-"mac80211: return the vif's chandef in ieee80211_cfg_get_channel()"
-
-Signed-off-by: Felix Fietkau <nbd@openwrt.org>
----
-
---- a/net/mac80211/chan.c
-+++ b/net/mac80211/chan.c
-@@ -932,6 +932,21 @@ ieee80211_vif_chanctx_reservation_comple
-       }
- }
-+static void
-+ieee80211_vif_update_chandef(struct ieee80211_sub_if_data *sdata,
-+                           const struct cfg80211_chan_def *chandef)
-+{
-+      struct ieee80211_sub_if_data *vlan;
-+
-+      sdata->vif.bss_conf.chandef = *chandef;
-+
-+      if (sdata->vif.type != NL80211_IFTYPE_AP)
-+              return;
-+
-+      list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list)
-+              vlan->vif.bss_conf.chandef = *chandef;
-+}
-+
- static int
- ieee80211_vif_use_reserved_reassign(struct ieee80211_sub_if_data *sdata)
- {
-@@ -994,7 +1009,7 @@ ieee80211_vif_use_reserved_reassign(stru
-       if (sdata->vif.bss_conf.chandef.width != sdata->reserved_chandef.width)
-               changed = BSS_CHANGED_BANDWIDTH;
--      sdata->vif.bss_conf.chandef = sdata->reserved_chandef;
-+      ieee80211_vif_update_chandef(sdata, &sdata->reserved_chandef);
-       if (changed)
-               ieee80211_bss_info_change_notify(sdata, changed);
-@@ -1336,7 +1351,7 @@ static int ieee80211_vif_use_reserved_sw
-                           sdata->reserved_chandef.width)
-                               changed = BSS_CHANGED_BANDWIDTH;
--                      sdata->vif.bss_conf.chandef = sdata->reserved_chandef;
-+                      ieee80211_vif_update_chandef(sdata, &sdata->reserved_chandef);
-                       if (changed)
-                               ieee80211_bss_info_change_notify(sdata,
-                                                                changed);
-@@ -1507,7 +1522,7 @@ int ieee80211_vif_use_channel(struct iee
-               goto out;
-       }
--      sdata->vif.bss_conf.chandef = *chandef;
-+      ieee80211_vif_update_chandef(sdata, chandef);
-       ret = ieee80211_assign_vif_chanctx(sdata, ctx);
-       if (ret) {
-@@ -1649,7 +1664,7 @@ int ieee80211_vif_change_bandwidth(struc
-               break;
-       }
--      sdata->vif.bss_conf.chandef = *chandef;
-+      ieee80211_vif_update_chandef(sdata, chandef);
-       ieee80211_recalc_chanctx_chantype(local, ctx);
---- a/net/mac80211/iface.c
-+++ b/net/mac80211/iface.c
-@@ -520,6 +520,7 @@ int ieee80211_do_open(struct wireless_de
-               sdata->vif.cab_queue = master->vif.cab_queue;
-               memcpy(sdata->vif.hw_queue, master->vif.hw_queue,
-                      sizeof(sdata->vif.hw_queue));
-+              sdata->vif.bss_conf.chandef = master->vif.bss_conf.chandef;
-               break;
-               }
-       case NL80211_IFTYPE_AP:
diff --git a/package/kernel/mac80211/patches/324-ath9k_hw-fix-hardware-queue-allocation.patch b/package/kernel/mac80211/patches/324-ath9k_hw-fix-hardware-queue-allocation.patch
deleted file mode 100644 (file)
index 8eba1f2..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-From: Felix Fietkau <nbd@openwrt.org>
-Date: Sun, 30 Nov 2014 20:30:46 +0100
-Subject: [PATCH] ath9k_hw: fix hardware queue allocation
-
-The driver passes the desired hardware queue index for a WMM data queue
-in qinfo->tqi_subtype. This was ignored in ath9k_hw_setuptxqueue, which
-instead relied on the order in which the function is called.
-
-Cc: stable@vger.kernel.org
-Reported-by: Hubert Feurstein <h.feurstein@gmail.com>
-Signed-off-by: Felix Fietkau <nbd@openwrt.org>
----
-
---- a/drivers/net/wireless/ath/ath9k/mac.c
-+++ b/drivers/net/wireless/ath/ath9k/mac.c
-@@ -311,14 +311,7 @@ int ath9k_hw_setuptxqueue(struct ath_hw 
-               q = ATH9K_NUM_TX_QUEUES - 3;
-               break;
-       case ATH9K_TX_QUEUE_DATA:
--              for (q = 0; q < ATH9K_NUM_TX_QUEUES; q++)
--                      if (ah->txq[q].tqi_type ==
--                          ATH9K_TX_QUEUE_INACTIVE)
--                              break;
--              if (q == ATH9K_NUM_TX_QUEUES) {
--                      ath_err(common, "No available TX queue\n");
--                      return -1;
--              }
-+              q = qinfo->tqi_subtype;
-               break;
-       default:
-               ath_err(common, "Invalid TX queue type: %u\n", type);
diff --git a/package/kernel/mac80211/patches/325-ath9k-fix-BE-BK-queue-order.patch b/package/kernel/mac80211/patches/325-ath9k-fix-BE-BK-queue-order.patch
deleted file mode 100644 (file)
index 3087b0c..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-From: Felix Fietkau <nbd@openwrt.org>
-Date: Sun, 30 Nov 2014 20:34:16 +0100
-Subject: [PATCH] ath9k: fix BE/BK queue order
-
-Hardware queues are ordered by priority. Use queue index 0 for BK, which
-has lower priority than BE.
-
-Cc: stable@vger.kernel.org
-Signed-off-by: Felix Fietkau <nbd@openwrt.org>
----
-
---- a/drivers/net/wireless/ath/ath9k/hw.h
-+++ b/drivers/net/wireless/ath/ath9k/hw.h
-@@ -217,8 +217,8 @@
- #define AH_WOW_BEACON_MISS            BIT(3)
- enum ath_hw_txq_subtype {
--      ATH_TXQ_AC_BE = 0,
--      ATH_TXQ_AC_BK = 1,
-+      ATH_TXQ_AC_BK = 0,
-+      ATH_TXQ_AC_BE = 1,
-       ATH_TXQ_AC_VI = 2,
-       ATH_TXQ_AC_VO = 3,
- };
diff --git a/package/kernel/mac80211/patches/326-ath5k-fix-hardware-queue-index-assignment.patch b/package/kernel/mac80211/patches/326-ath5k-fix-hardware-queue-index-assignment.patch
deleted file mode 100644 (file)
index 81807a9..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-From: Felix Fietkau <nbd@openwrt.org>
-Date: Sun, 30 Nov 2014 21:51:12 +0100
-Subject: [PATCH] ath5k: fix hardware queue index assignment
-
-Like with ath9k, ath5k queues also need to be ordered by priority.
-queue_info->tqi_subtype already contains the correct index, so use it
-instead of relying on the order of ath5k_hw_setup_tx_queue calls.
-
-Cc: stable@vger.kernel.org
-Signed-off-by: Felix Fietkau <nbd@openwrt.org>
----
-
---- a/drivers/net/wireless/ath/ath5k/qcu.c
-+++ b/drivers/net/wireless/ath/ath5k/qcu.c
-@@ -225,13 +225,7 @@ ath5k_hw_setup_tx_queue(struct ath5k_hw 
-       } else {
-               switch (queue_type) {
-               case AR5K_TX_QUEUE_DATA:
--                      for (queue = AR5K_TX_QUEUE_ID_DATA_MIN;
--                              ah->ah_txq[queue].tqi_type !=
--                              AR5K_TX_QUEUE_INACTIVE; queue++) {
--
--                              if (queue > AR5K_TX_QUEUE_ID_DATA_MAX)
--                                      return -EINVAL;
--                      }
-+                      queue = queue_info->tqi_subtype;
-                       break;
-               case AR5K_TX_QUEUE_UAPSD:
-                       queue = AR5K_TX_QUEUE_ID_UAPSD;
diff --git a/package/kernel/mac80211/patches/327-ath10k-fix-low-TX-rates-when-IBSS-and-HT.patch b/package/kernel/mac80211/patches/327-ath10k-fix-low-TX-rates-when-IBSS-and-HT.patch
deleted file mode 100644 (file)
index 09f1e25..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-From: Janusz Dziedzic <janusz.dziedzic@tieto.com>
-Date: Tue, 16 Dec 2014 09:52:59 +0100
-Subject: [PATCH] ath10k: fix low TX rates when IBSS and HT
-
-This fix TX problem when IBSS used in HT mode.
-Before we used 6Mbps all the time for TX direction.
-
-Reported-by: Yeoh Chun-Yeow <yeohchunyeow@gmail.com>
-Signed-off-by: Janusz Dziedzic <janusz.dziedzic@tieto.com>
----
-
---- a/drivers/net/wireless/ath/ath10k/mac.c
-+++ b/drivers/net/wireless/ath/ath10k/mac.c
-@@ -1375,9 +1375,16 @@ static void ath10k_peer_assoc_h_qos(stru
-               if (vif->bss_conf.qos)
-                       arg->peer_flags |= WMI_PEER_QOS;
-               break;
-+      case WMI_VDEV_TYPE_IBSS:
-+              if (sta->wme)
-+                      arg->peer_flags |= WMI_PEER_QOS;
-+              break;
-       default:
-               break;
-       }
-+
-+      ath10k_dbg(ar, ATH10K_DBG_MAC, "mac peer %pM qos %d\n",
-+                 sta->addr, !!(arg->peer_flags & WMI_PEER_QOS));
- }
- static void ath10k_peer_assoc_h_phymode(struct ath10k *ar,
diff --git a/package/kernel/mac80211/patches/328-ath10k-send-re-assoc-peer-command-when-NSS-changed.patch b/package/kernel/mac80211/patches/328-ath10k-send-re-assoc-peer-command-when-NSS-changed.patch
deleted file mode 100644 (file)
index 56290cd..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-From: Janusz Dziedzic <janusz.dziedzic@tieto.com>
-Date: Tue, 16 Dec 2014 09:53:00 +0100
-Subject: [PATCH] ath10k: send (re)assoc peer command when NSS changed
-
-Assoc peer command contain information about NSS.
-When we will get IEEE80211_RC_NSS_CHANGED we should
-also send (re) assoc peer command to be sure firmware
-will know about it and RC will work correctly.
-
-Signed-off-by: Janusz Dziedzic <janusz.dziedzic@tieto.com>
----
-
---- a/drivers/net/wireless/ath/ath10k/mac.c
-+++ b/drivers/net/wireless/ath/ath10k/mac.c
-@@ -3497,8 +3497,9 @@ static void ath10k_sta_rc_update_wk(stru
-                                   sta->addr, smps, err);
-       }
--      if (changed & IEEE80211_RC_SUPP_RATES_CHANGED) {
--              ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM supp rates\n",
-+      if (changed & IEEE80211_RC_SUPP_RATES_CHANGED ||
-+          changed & IEEE80211_RC_NSS_CHANGED) {
-+              ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM supp rates/nss\n",
-                          sta->addr);
-               err = ath10k_station_assoc(ar, arvif->vif, sta, true);
diff --git a/package/kernel/mac80211/patches/329-ath9k-fix-race-condition-in-irq-processing-during-ha.patch b/package/kernel/mac80211/patches/329-ath9k-fix-race-condition-in-irq-processing-during-ha.patch
deleted file mode 100644 (file)
index 69b21e7..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-From: Felix Fietkau <nbd@openwrt.org>
-Date: Wed, 14 Jan 2015 14:13:15 +0100
-Subject: [PATCH] ath9k: fix race condition in irq processing during hardware
- reset
-
-To fix invalid hardware accesses, the commit
-"ath9k: do not access hardware on IRQs during reset" made the irq
-handler ignore interrupts emitted after queueing a hardware reset (which
-disables the IRQ). This left a small time window for the IRQ to get
-re-enabled by the tasklet, which caused IRQ storms.
-Instead of returning IRQ_NONE when ATH_OP_HW_RESET is set, disable the
-IRQ entirely for the duration of the reset.
-
-Signed-off-by: Felix Fietkau <nbd@openwrt.org>
----
-
---- a/drivers/net/wireless/ath/ath9k/main.c
-+++ b/drivers/net/wireless/ath/ath9k/main.c
-@@ -285,6 +285,7 @@ static int ath_reset_internal(struct ath
-       __ath_cancel_work(sc);
-+      disable_irq(sc->irq);
-       tasklet_disable(&sc->intr_tq);
-       tasklet_disable(&sc->bcon_tasklet);
-       spin_lock_bh(&sc->sc_pcu_lock);
-@@ -331,6 +332,7 @@ static int ath_reset_internal(struct ath
-               r = -EIO;
- out:
-+      enable_irq(sc->irq);
-       spin_unlock_bh(&sc->sc_pcu_lock);
-       tasklet_enable(&sc->bcon_tasklet);
-       tasklet_enable(&sc->intr_tq);
-@@ -512,9 +514,6 @@ irqreturn_t ath_isr(int irq, void *dev)
-       if (!ah || test_bit(ATH_OP_INVALID, &common->op_flags))
-               return IRQ_NONE;
--      if (!AR_SREV_9100(ah) && test_bit(ATH_OP_HW_RESET, &common->op_flags))
--              return IRQ_NONE;
--
-       /* shared irq, not for us */
-       if (!ath9k_hw_intrpend(ah))
-               return IRQ_NONE;
-@@ -529,7 +528,7 @@ irqreturn_t ath_isr(int irq, void *dev)
-       ath9k_debug_sync_cause(sc, sync_cause);
-       status &= ah->imask;    /* discard unasked-for bits */
--      if (AR_SREV_9100(ah) && test_bit(ATH_OP_HW_RESET, &common->op_flags))
-+      if (test_bit(ATH_OP_HW_RESET, &common->op_flags))
-               return IRQ_HANDLED;
-       /*
diff --git a/package/kernel/mac80211/patches/330-ath5k-fix-spontaneus-AR5312-freezes.patch b/package/kernel/mac80211/patches/330-ath5k-fix-spontaneus-AR5312-freezes.patch
deleted file mode 100644 (file)
index aacadba..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-From: Sergey Ryazanov <ryazanov.s.a@gmail.com>
-Date: Tue, 3 Feb 2015 22:37:26 +0300
-Subject: [PATCH] ath5k: fix spontaneus AR5312 freezes
-
-Sometimes while CPU have some load and ath5k doing the wireless
-interface reset the whole WiSoC completely freezes. Set of tests shows
-that using atomic delay function while we wait interface reset helps to
-avoid such freezes.
-
-The easiest way to reproduce this issue: create a station interface,
-start continous scan with wpa_supplicant and load CPU by something. Or
-just create multiple station interfaces and put them all in continous
-scan.
-
-This patch partially reverts the commit 1846ac3dbec0 ("ath5k: Use
-usleep_range where possible"), which replaces initial udelay()
-by usleep_range().
-
-I do not know actual source of this issue, but all looks like that HW
-freeze is caused by transaction on internal SoC bus, while wireless
-block is in reset state.
-
-Also I should note that I do not know how many chips are affected, but I
-did not see this issue with chips, other than AR5312.
-
-CC: Jiri Slaby <jirislaby@gmail.com>
-CC: Nick Kossifidis <mickflemm@gmail.com>
-CC: Luis R. Rodriguez <mcgrof@do-not-panic.com>
-Fixes: 1846ac3dbec0 ("ath5k: Use usleep_range where possible")
-Reported-by: Christophe Prevotaux <c.prevotaux@rural-networks.com>
-Tested-by: Christophe Prevotaux <c.prevotaux@rural-networks.com>
-Tested-by: Eric Bree <ebree@nltinc.com>
-Signed-off-by: Sergey Ryazanov <ryazanov.s.a@gmail.com>
----
---- a/drivers/net/wireless/ath/ath5k/reset.c
-+++ b/drivers/net/wireless/ath/ath5k/reset.c
-@@ -478,7 +478,7 @@ ath5k_hw_wisoc_reset(struct ath5k_hw *ah
-       regval = ioread32(reg);
-       iowrite32(regval | val, reg);
-       regval = ioread32(reg);
--      usleep_range(100, 150);
-+      udelay(100);    /* NB: should be atomic */
-       /* Bring BB/MAC out of reset */
-       iowrite32(regval & ~val, reg);
diff --git a/package/kernel/mac80211/patches/331-ath5k-channel-change-fix.patch b/package/kernel/mac80211/patches/331-ath5k-channel-change-fix.patch
deleted file mode 100644 (file)
index e776063..0000000
+++ /dev/null
@@ -1,145 +0,0 @@
-From a5d37f41d298a2a202296909892dd01e2bf071c7 Mon Sep 17 00:00:00 2001
-From: Sergey Ryazanov <ryazanov.s.a@gmail.com>
-Date: Wed, 4 Mar 2015 00:44:37 +0300
-Subject: [PATCH] ath5k: channel change fix
-
-ath5k updates the channel pointer and after that it stops the Rx logic
-and apply channel to HW. In case of channel switch, such sequence
-creates a small window when a frame, which is received on the old
-channel is considered as a frame received on the new one.
-
-The most notable consequence of this situation occurs during the switch
-from 2 GHz band (CCK+OFDM) to the 5GHz band (OFDM-only). Frame received
-with CCK rate, e.g. beacon received at the 1mbps, causes the following
-warning:
-
-  WARNING: at ath5k/base.c:589 ath5k_tasklet_rx+0x318/0x6ec [ath5k]()
-  invalid hw_rix: 1a
-  [..]
-  Call Trace:
-  [<802656a8>] show_stack+0x48/0x70
-  [<802dd92c>] warn_slowpath_common+0x88/0xbc
-  [<802dd98c>] warn_slowpath_fmt+0x2c/0x38
-  [<81b51be8>] ath5k_tasklet_rx+0x318/0x6ec [ath5k]
-  [<8028ac64>] tasklet_action+0x8c/0xf0
-  [<80075804>] __do_softirq+0x180/0x32c
-  [<80196ce8>] irq_exit+0x54/0x70
-  [<80041848>] ret_from_irq+0x0/0x4
-  [<80182fdc>] ioread32+0x4/0xc
-  [<81b4c42c>] ath5k_hw_set_sleep_clock+0x2ec/0x474 [ath5k]
-  [<81b4cf28>] ath5k_hw_reset+0x50/0xeb8 [ath5k]
-  [<81b50900>] ath5k_reset+0xd4/0x310 [ath5k]
-  [<81b557e8>] ath5k_config+0x4c/0x104 [ath5k]
-  [<80d01770>] ieee80211_hw_config+0x2f4/0x35c [mac80211]
-  [<80d09aa8>] ieee80211_scan_work+0x2e4/0x414 [mac80211]
-  [<8022c3f4>] process_one_work+0x28c/0x400
-  [<802df8f8>] worker_thread+0x258/0x3c0
-  [<801b5710>] kthread+0xe0/0xec
-  [<800418a8>] ret_from_kernel_thread+0x14/0x1c
-
-The easiest way to reproduce this warning is to run scan with dualband
-NIC in noisy environments, when the channel 11 runs multiple APs. In my
-tests if the APs num >= 12, the warning appears in the first few
-seconds of scanning.
-
-In order to fix this, the Rx disable code moved to a higher level and
-placed before the channel pointer update. This is also makes the code a
-bit more symmetrical, since we disable and enable the Rx in the same
-function.
-
-In fact, at the pointer update time new frames should not appear,
-because interrupt generation at this point should already be disabled.
-The next patch should address this issue.
-
-CC: Jiri Slaby <jirislaby@gmail.com>
-CC: Nick Kossifidis <mickflemm@gmail.com>
-CC: Luis R. Rodriguez <mcgrof@do-not-panic.com>
-Reported-by: Christophe Prevotaux <cprevotaux@nltinc.com>
-Tested-by: Christophe Prevotaux <cprevotaux@nltinc.com>
-Tested-by: Eric Bree <ebree@nltinc.com>
-Signed-off-by: Sergey Ryazanov <ryazanov.s.a@gmail.com>
----
- drivers/net/wireless/ath/ath5k/base.c  | 24 +++++++++++++++++++++---
- drivers/net/wireless/ath/ath5k/reset.c | 24 ------------------------
- 2 files changed, 21 insertions(+), 27 deletions(-)
-
-diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
-index bc9cb35..34b2f15 100644
---- a/drivers/net/wireless/ath/ath5k/base.c
-+++ b/drivers/net/wireless/ath/ath5k/base.c
-@@ -2858,7 +2858,7 @@ ath5k_reset(struct ath5k_hw *ah, struct ieee80211_channel *chan,
- {
-       struct ath_common *common = ath5k_hw_common(ah);
-       int ret, ani_mode;
--      bool fast;
-+      bool fast = chan && modparam_fastchanswitch ? 1 : 0;
-       ATH5K_DBG(ah, ATH5K_DEBUG_RESET, "resetting\n");
-@@ -2876,11 +2876,29 @@ ath5k_reset(struct ath5k_hw *ah, struct ieee80211_channel *chan,
-        * so we should also free any remaining
-        * tx buffers */
-       ath5k_drain_tx_buffs(ah);
-+
-+      /* Stop PCU */
-+      ath5k_hw_stop_rx_pcu(ah);
-+
-+      /* Stop DMA
-+       *
-+       * Note: If DMA didn't stop continue
-+       * since only a reset will fix it.
-+       */
-+      ret = ath5k_hw_dma_stop(ah);
-+
-+      /* RF Bus grant won't work if we have pending
-+       * frames
-+       */
-+      if (ret && fast) {
-+              ATH5K_DBG(ah, ATH5K_DEBUG_RESET,
-+                        "DMA didn't stop, falling back to normal reset\n");
-+              fast = false;
-+      }
-+
-       if (chan)
-               ah->curchan = chan;
--      fast = ((chan != NULL) && modparam_fastchanswitch) ? 1 : 0;
--
-       ret = ath5k_hw_reset(ah, ah->opmode, ah->curchan, fast, skip_pcu);
-       if (ret) {
-               ATH5K_ERR(ah, "can't reset hardware (%d)\n", ret);
-diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c
-index b9b651e..99e62f9 100644
---- a/drivers/net/wireless/ath/ath5k/reset.c
-+++ b/drivers/net/wireless/ath/ath5k/reset.c
-@@ -1169,30 +1169,6 @@ ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
-       if (ah->ah_version == AR5K_AR5212)
-               ath5k_hw_set_sleep_clock(ah, false);
--      /*
--       * Stop PCU
--       */
--      ath5k_hw_stop_rx_pcu(ah);
--
--      /*
--       * Stop DMA
--       *
--       * Note: If DMA didn't stop continue
--       * since only a reset will fix it.
--       */
--      ret = ath5k_hw_dma_stop(ah);
--
--      /* RF Bus grant won't work if we have pending
--       * frames */
--      if (ret && fast) {
--              ATH5K_DBG(ah, ATH5K_DEBUG_RESET,
--                      "DMA didn't stop, falling back to normal reset\n");
--              fast = false;
--              /* Non fatal, just continue with
--               * normal reset */
--              ret = 0;
--      }
--
-       mode = channel->hw_value;
-       switch (mode) {
-       case AR5K_MODE_11A:
diff --git a/package/kernel/mac80211/patches/332-ath5k-fix-reset-race.patch b/package/kernel/mac80211/patches/332-ath5k-fix-reset-race.patch
deleted file mode 100644 (file)
index 4a3abaa..0000000
+++ /dev/null
@@ -1,104 +0,0 @@
-From d8d4050dff457b79ad7e9356103cad557c338532 Mon Sep 17 00:00:00 2001
-From: Sergey Ryazanov <ryazanov.s.a@gmail.com>
-Date: Wed, 4 Mar 2015 03:16:34 +0300
-Subject: [PATCH] ath5k: fix reset race
-
-To prepare for reset ath5k should finish all asynchronous tasks. At
-first, it disables the interrupt generation, then it waits for the
-interrupt handler and tasklets completion, and then proceeds to the HW
-configuration update. But it does not consider that the interrupt
-handler or tasklet re-enables the interrupt generation. And we fall in a
-situation when ath5k assumes that interrupts are disabled, but it is
-not.
-
-This can lead to different consequences, such as reception of the frame,
-when we do not expect it. Under certain circumstances, this can lead to
-the following warning:
-
-  WARNING: at ath5k/base.c:589 ath5k_tasklet_rx+0x318/0x6ec [ath5k]()
-  invalid hw_rix: 1a
-  [..]
-  Call Trace:
-  [<802656a8>] show_stack+0x48/0x70
-  [<802dd92c>] warn_slowpath_common+0x88/0xbc
-  [<802dd98c>] warn_slowpath_fmt+0x2c/0x38
-  [<81b51be8>] ath5k_tasklet_rx+0x318/0x6ec [ath5k]
-  [<8028ac64>] tasklet_action+0x8c/0xf0
-  [<80075804>] __do_softirq+0x180/0x32c
-  [<80196ce8>] irq_exit+0x54/0x70
-  [<80041848>] ret_from_irq+0x0/0x4
-  [<80182fdc>] ioread32+0x4/0xc
-  [<81b4c42c>] ath5k_hw_set_sleep_clock+0x2ec/0x474 [ath5k]
-  [<81b4cf28>] ath5k_hw_reset+0x50/0xeb8 [ath5k]
-  [<81b50900>] ath5k_reset+0xd4/0x310 [ath5k]
-  [<81b557e8>] ath5k_config+0x4c/0x104 [ath5k]
-  [<80d01770>] ieee80211_hw_config+0x2f4/0x35c [mac80211]
-  [<80d09aa8>] ieee80211_scan_work+0x2e4/0x414 [mac80211]
-  [<8022c3f4>] process_one_work+0x28c/0x400
-  [<802df8f8>] worker_thread+0x258/0x3c0
-  [<801b5710>] kthread+0xe0/0xec
-  [<800418a8>] ret_from_kernel_thread+0x14/0x1c
-
-Fix this issue by adding a new status flag, which forbids to re-enable
-the interrupt generation until the HW configuration is completed.
-
-Note: previous patch, which reorders the Rx disable code helps to avoid
-the above warning, but not fixes the root cause of unexpected frame
-receiving.
-
-CC: Jiri Slaby <jirislaby@gmail.com>
-CC: Nick Kossifidis <mickflemm@gmail.com>
-CC: Luis R. Rodriguez <mcgrof@do-not-panic.com>
-Reported-by: Christophe Prevotaux <cprevotaux@nltinc.com>
-Tested-by: Christophe Prevotaux <cprevotaux@nltinc.com>
-Tested-by: Eric Bree <ebree@nltinc.com>
-Signed-off-by: Sergey Ryazanov <ryazanov.s.a@gmail.com>
----
- drivers/net/wireless/ath/ath5k/ath5k.h | 1 +
- drivers/net/wireless/ath/ath5k/base.c  | 7 +++++++
- 2 files changed, 8 insertions(+)
-
-diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h
-index 1ed7a88..7ca0d6f 100644
---- a/drivers/net/wireless/ath/ath5k/ath5k.h
-+++ b/drivers/net/wireless/ath/ath5k/ath5k.h
-@@ -1283,6 +1283,7 @@ struct ath5k_hw {
- #define ATH_STAT_PROMISC      1
- #define ATH_STAT_LEDSOFT      2               /* enable LED gpio status */
- #define ATH_STAT_STARTED      3               /* opened & irqs enabled */
-+#define ATH_STAT_RESET                4               /* hw reset */
-       unsigned int            filter_flags;   /* HW flags, AR5K_RX_FILTER_* */
-       unsigned int            fif_filter_flags; /* Current FIF_* filter flags */
-diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
-index 34b2f15..41848e1 100644
---- a/drivers/net/wireless/ath/ath5k/base.c
-+++ b/drivers/net/wireless/ath/ath5k/base.c
-@@ -1523,6 +1523,9 @@ ath5k_set_current_imask(struct ath5k_hw *ah)
-       enum ath5k_int imask;
-       unsigned long flags;
-+      if (test_bit(ATH_STAT_RESET, ah->status))
-+              return;
-+
-       spin_lock_irqsave(&ah->irqlock, flags);
-       imask = ah->imask;
-       if (ah->rx_pending)
-@@ -2862,6 +2865,8 @@ ath5k_reset(struct ath5k_hw *ah, struct ieee80211_channel *chan,
-       ATH5K_DBG(ah, ATH5K_DEBUG_RESET, "resetting\n");
-+      __set_bit(ATH_STAT_RESET, ah->status);
-+
-       ath5k_hw_set_imr(ah, 0);
-       synchronize_irq(ah->irq);
-       ath5k_stop_tasklets(ah);
-@@ -2952,6 +2957,8 @@ ath5k_reset(struct ath5k_hw *ah, struct ieee80211_channel *chan,
-        */
- /*    ath5k_chan_change(ah, c); */
-+      __clear_bit(ATH_STAT_RESET, ah->status);
-+
-       ath5k_beacon_config(ah);
-       /* intrs are enabled by ath5k_beacon_config */
index 229fc46..640de53 100644 (file)
@@ -14,7 +14,7 @@
  ccflags-y += -D__CHECK_ENDIAN__
 --- a/drivers/net/wireless/ath/ath.h
 +++ b/drivers/net/wireless/ath/ath.h
-@@ -301,13 +301,6 @@ void _ath_dbg(struct ath_common *common,
+@@ -313,13 +313,6 @@ void _ath_dbg(struct ath_common *common,
  #endif /* CPTCFG_ATH_DEBUG */
  
  /** Returns string describing opmode, or NULL if unknown mode. */
index b0cef87..4a997f1 100644 (file)
@@ -4,8 +4,8 @@
  module_param_named(nohwcrypt, ath9k_modparam_nohwcrypt, int, 0444);
  MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption");
  
--int led_blink;
-+int led_blink = 1;
- module_param_named(blink, led_blink, int, 0444);
+-int ath9k_led_blink;
++int ath9k_led_blink = 1;
+ module_param_named(blink, ath9k_led_blink, int, 0444);
  MODULE_PARM_DESC(blink, "Enable LED blink on activity");
  
index 3c1bfee..1c32a06 100644 (file)
@@ -59,7 +59,7 @@
        ---help---
 --- a/.local-symbols
 +++ b/.local-symbols
-@@ -116,6 +116,7 @@ RTL8187_LEDS=
+@@ -89,6 +89,7 @@ RTL8187_LEDS=
  ATH_COMMON=
  ATH_CARDS=
  ATH_DEBUG=
index 85f1fc0..1476953 100644 (file)
@@ -1,6 +1,6 @@
 --- a/net/wireless/reg.c
 +++ b/net/wireless/reg.c
-@@ -2112,6 +2112,8 @@ void regulatory_hint_country_ie(struct w
+@@ -2368,6 +2368,8 @@ void regulatory_hint_country_ie(struct w
        enum environment_cap env = ENVIRON_ANY;
        struct regulatory_request *request = NULL, *lr;
  
@@ -9,7 +9,7 @@
        /* IE len must be evenly divisible by 2 */
        if (country_ie_len & 0x01)
                return;
-@@ -2308,6 +2310,7 @@ static void restore_regulatory_settings(
+@@ -2571,6 +2573,7 @@ static void restore_regulatory_settings(
  
  void regulatory_hint_disconnect(void)
  {
index 16bf144..443387c 100644 (file)
@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/ath/ath9k/init.c
 +++ b/drivers/net/wireless/ath/ath9k/init.c
-@@ -684,6 +684,7 @@ static const struct ieee80211_iface_limi
+@@ -704,6 +704,7 @@ static const struct ieee80211_iface_limi
                                 BIT(NL80211_IFTYPE_AP) },
        { .max = 1,     .types = BIT(NL80211_IFTYPE_P2P_CLIENT) |
                                 BIT(NL80211_IFTYPE_P2P_GO) },
index 23f9435..58dd26f 100644 (file)
@@ -18,7 +18,7 @@
                goto end;
 --- a/drivers/net/wireless/ath/ath5k/base.c
 +++ b/drivers/net/wireless/ath/ath5k/base.c
-@@ -1962,7 +1962,7 @@ ath5k_beacon_send(struct ath5k_hw *ah)
+@@ -1965,7 +1965,7 @@ ath5k_beacon_send(struct ath5k_hw *ah)
        }
  
        if ((ah->opmode == NL80211_IFTYPE_AP && ah->num_ap_vifs +
@@ -27,7 +27,7 @@
                        ah->opmode == NL80211_IFTYPE_MESH_POINT) {
                u64 tsf = ath5k_hw_get_tsf64(ah);
                u32 tsftu = TSF_TO_TU(tsf);
-@@ -2048,7 +2048,7 @@ ath5k_beacon_update_timers(struct ath5k_
+@@ -2051,7 +2051,7 @@ ath5k_beacon_update_timers(struct ath5k_
  
        intval = ah->bintval & AR5K_BEACON_PERIOD;
        if (ah->opmode == NL80211_IFTYPE_AP && ah->num_ap_vifs
@@ -36,7 +36,7 @@
                intval /= ATH_BCBUF;    /* staggered multi-bss beacons */
                if (intval < 15)
                        ATH5K_WARN(ah, "intval %u is too low, min 15\n",
-@@ -2515,6 +2515,7 @@ static const struct ieee80211_iface_limi
+@@ -2518,6 +2518,7 @@ static const struct ieee80211_iface_limi
                                 BIT(NL80211_IFTYPE_MESH_POINT) |
  #endif
                                 BIT(NL80211_IFTYPE_AP) },
index d2c6c5f..9b12d77 100644 (file)
@@ -121,7 +121,7 @@ drivers/net/wireless/ath/ath5k/debug.c |   86 ++++++++++++++++++++++++++++++++
        debugfs_create_file("antenna", S_IWUSR | S_IRUSR, phydir, ah,
 --- a/drivers/net/wireless/ath/ath5k/ath5k.h
 +++ b/drivers/net/wireless/ath/ath5k/ath5k.h
-@@ -1370,6 +1370,7 @@ struct ath5k_hw {
+@@ -1371,6 +1371,7 @@ struct ath5k_hw {
        u8                      ah_coverage_class;
        bool                    ah_ack_bitrate_high;
        u8                      ah_bwmode;
index dfcbe56..c6f50be 100644 (file)
@@ -1,7 +1,7 @@
 --- a/drivers/net/wireless/ath/ath9k/debug.c
 +++ b/drivers/net/wireless/ath/ath9k/debug.c
-@@ -1314,6 +1314,53 @@ void ath9k_deinit_debug(struct ath_softc
-       ath9k_spectral_deinit_debug(sc);
+@@ -1299,6 +1299,53 @@ void ath9k_deinit_debug(struct ath_softc
+       ath9k_cmn_spectral_deinit_debug(&sc->spec_priv);
  }
  
 +static ssize_t read_file_eeprom(struct file *file, char __user *user_buf,
  int ath9k_init_debug(struct ath_hw *ah)
  {
        struct ath_common *common = ath9k_hw_common(ah);
-@@ -1333,6 +1380,8 @@ int ath9k_init_debug(struct ath_hw *ah)
+@@ -1318,6 +1365,8 @@ int ath9k_init_debug(struct ath_hw *ah)
        ath9k_tx99_init_debug(sc);
-       ath9k_spectral_init_debug(sc);
+       ath9k_cmn_spectral_init_debug(&sc->spec_priv, sc->debug.debugfs_phy);
  
 +      debugfs_create_file("eeprom", S_IRUSR, sc->debug.debugfs_phy, sc,
 +                          &fops_eeprom);
-       debugfs_create_file("dma", S_IRUSR, sc->debug.debugfs_phy, sc,
-                           &fops_dma);
-       debugfs_create_file("interrupt", S_IRUSR, sc->debug.debugfs_phy, sc,
+       debugfs_create_devm_seqfile(sc->dev, "dma", sc->debug.debugfs_phy,
+                                   read_file_dma);
+       debugfs_create_devm_seqfile(sc->dev, "interrupt", sc->debug.debugfs_phy,
index 965cb6b..7a4c5d5 100644 (file)
@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/ath/ath9k/init.c
 +++ b/drivers/net/wireless/ath/ath9k/init.c
-@@ -990,23 +990,23 @@ static int __init ath9k_init(void)
+@@ -1012,23 +1012,23 @@ static int __init ath9k_init(void)
  {
        int error;
  
index eebf6fc..c818933 100644 (file)
@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/ath/ath9k/hw.c
 +++ b/drivers/net/wireless/ath/ath9k/hw.c
-@@ -356,13 +356,8 @@ static void ath9k_hw_init_config(struct 
+@@ -358,13 +358,8 @@ static void ath9k_hw_init_config(struct 
  
        ah->config.rx_intr_mitigation = true;
  
index 6766111..d4104f0 100644 (file)
@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/ath/ath9k/ath9k.h
 +++ b/drivers/net/wireless/ath/ath9k/ath9k.h
-@@ -88,7 +88,7 @@ int ath_descdma_setup(struct ath_softc *
+@@ -87,7 +87,7 @@ int ath_descdma_setup(struct ath_softc *
                (_l) &= ((_sz) - 1);            \
        } while (0)
  
index e8a92c4..a74f631 100644 (file)
@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/ath/ath9k/debug.c
 +++ b/drivers/net/wireless/ath/ath9k/debug.c
-@@ -1361,6 +1361,52 @@ static const struct file_operations fops
+@@ -1346,6 +1346,52 @@ static const struct file_operations fops
        .owner = THIS_MODULE
  };
  
  int ath9k_init_debug(struct ath_hw *ah)
  {
        struct ath_common *common = ath9k_hw_common(ah);
-@@ -1382,6 +1428,8 @@ int ath9k_init_debug(struct ath_hw *ah)
+@@ -1367,6 +1413,8 @@ int ath9k_init_debug(struct ath_hw *ah)
  
        debugfs_create_file("eeprom", S_IRUSR, sc->debug.debugfs_phy, sc,
                            &fops_eeprom);
 +      debugfs_create_file("chanbw", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
 +                          sc, &fops_chanbw);
-       debugfs_create_file("dma", S_IRUSR, sc->debug.debugfs_phy, sc,
-                           &fops_dma);
-       debugfs_create_file("interrupt", S_IRUSR, sc->debug.debugfs_phy, sc,
+       debugfs_create_devm_seqfile(sc->dev, "dma", sc->debug.debugfs_phy,
+                                   read_file_dma);
+       debugfs_create_devm_seqfile(sc->dev, "interrupt", sc->debug.debugfs_phy,
 --- a/drivers/net/wireless/ath/ath.h
 +++ b/drivers/net/wireless/ath/ath.h
-@@ -142,6 +142,7 @@ struct ath_common {
+@@ -148,6 +148,7 @@ struct ath_common {
        int debug_mask;
        enum ath_device_state state;
        unsigned long op_flags;
index 09c16dd..ec16eb4 100644 (file)
@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/ath/ath9k/hw.c
 +++ b/drivers/net/wireless/ath/ath9k/hw.c
-@@ -611,6 +611,7 @@ int ath9k_hw_init(struct ath_hw *ah)
+@@ -616,6 +616,7 @@ int ath9k_hw_init(struct ath_hw *ah)
  
        /* These are all the AR5008/AR9001/AR9002/AR9003 hardware family of chipsets */
        switch (ah->hw_version.devid) {
@@ -10,7 +10,7 @@
        case AR5416_AR9100_DEVID:
 --- a/drivers/net/wireless/ath/ath9k/hw.h
 +++ b/drivers/net/wireless/ath/ath9k/hw.h
-@@ -35,6 +35,7 @@
+@@ -36,6 +36,7 @@
  
  #define ATHEROS_VENDOR_ID     0x168c
  
@@ -20,7 +20,7 @@
  #define AR9160_DEVID_PCI      0x0027
 --- a/drivers/net/wireless/ath/ath9k/pci.c
 +++ b/drivers/net/wireless/ath/ath9k/pci.c
-@@ -664,6 +664,7 @@ static const struct pci_device_id ath_pc
+@@ -751,6 +751,7 @@ static const struct pci_device_id ath_pc
          .driver_data = ATH9K_PCI_BT_ANT_DIV },
  #endif
  
index 36e51c8..9712d6e 100644 (file)
@@ -1,6 +1,6 @@
 --- a/include/net/cfg80211.h
 +++ b/include/net/cfg80211.h
-@@ -2245,6 +2245,7 @@ struct cfg80211_qos_map {
+@@ -2320,6 +2320,7 @@ struct cfg80211_qos_map {
   *    (as advertised by the nl80211 feature flag.)
   * @get_tx_power: store the current TX power into the dbm variable;
   *    return 0 if successful
@@ -8,7 +8,7 @@
   *
   * @set_wds_peer: set the WDS peer for a WDS interface
   *
-@@ -2495,6 +2496,7 @@ struct cfg80211_ops {
+@@ -2576,6 +2577,7 @@ struct cfg80211_ops {
                                enum nl80211_tx_power_setting type, int mbm);
        int     (*get_tx_power)(struct wiphy *wiphy, struct wireless_dev *wdev,
                                int *dbm);
@@ -18,7 +18,7 @@
                                const u8 *addr);
 --- a/include/net/mac80211.h
 +++ b/include/net/mac80211.h
-@@ -1078,6 +1078,7 @@ enum ieee80211_smps_mode {
+@@ -1138,6 +1138,7 @@ enum ieee80211_smps_mode {
   *
   * @power_level: requested transmit power (in dBm), backward compatibility
   *    value only that is set to the minimum of all interfaces
@@ -26,7 +26,7 @@
   *
   * @chandef: the channel definition to tune to
   * @radar_enabled: whether radar detection is enabled
-@@ -1099,6 +1100,7 @@ struct ieee80211_conf {
+@@ -1159,6 +1160,7 @@ struct ieee80211_conf {
        u32 flags;
        int power_level, dynamic_ps_timeout;
        int max_sleep_period;
        u8 ps_dtim_period;
 --- a/include/uapi/linux/nl80211.h
 +++ b/include/uapi/linux/nl80211.h
-@@ -1656,6 +1656,9 @@ enum nl80211_commands {
-  * @NL80211_ATTR_SMPS_MODE: SMPS mode to use (ap mode). see
-  *    &enum nl80211_smps_mode.
+@@ -1760,6 +1760,9 @@ enum nl80211_commands {
+  * @NL80211_ATTR_REG_INDOOR: flag attribute, if set indicates that the device
+  *      is operating in an indoor environment.
   *
 + * @NL80211_ATTR_WIPHY_ANTENNA_GAIN: Configured antenna gain. Used to reduce
 + *    transmit power to stay within regulatory limits. u32, dBi.
 + *
+  * @NUM_NL80211_ATTR: total number of nl80211_attrs available
   * @NL80211_ATTR_MAX: highest attribute number currently defined
   * @__NL80211_ATTR_AFTER_LAST: internal use
-  */
-@@ -2008,6 +2011,8 @@ enum nl80211_attrs {
+@@ -2129,6 +2132,8 @@ enum nl80211_attrs {
  
-       NL80211_ATTR_SMPS_MODE,
+       NL80211_ATTR_REG_INDOOR,
  
 +      NL80211_ATTR_WIPHY_ANTENNA_GAIN,
 +
@@ -57,7 +57,7 @@
        __NL80211_ATTR_AFTER_LAST,
 --- a/net/mac80211/cfg.c
 +++ b/net/mac80211/cfg.c
-@@ -2155,6 +2155,19 @@ static int ieee80211_get_tx_power(struct
+@@ -2208,6 +2208,19 @@ static int ieee80211_get_tx_power(struct
        return 0;
  }
  
@@ -77,7 +77,7 @@
  static int ieee80211_set_wds_peer(struct wiphy *wiphy, struct net_device *dev,
                                  const u8 *addr)
  {
-@@ -3723,6 +3736,7 @@ const struct cfg80211_ops mac80211_confi
+@@ -3771,6 +3784,7 @@ const struct cfg80211_ops mac80211_confi
        .set_wiphy_params = ieee80211_set_wiphy_params,
        .set_tx_power = ieee80211_set_tx_power,
        .get_tx_power = ieee80211_get_tx_power,
@@ -87,7 +87,7 @@
        CFG80211_TESTMODE_CMD(ieee80211_testmode_cmd)
 --- a/net/mac80211/ieee80211_i.h
 +++ b/net/mac80211/ieee80211_i.h
-@@ -1339,6 +1339,7 @@ struct ieee80211_local {
+@@ -1330,6 +1330,7 @@ struct ieee80211_local {
        int dynamic_ps_forced_timeout;
  
        int user_power_level; /* in dBm, for all interfaces */
        local->user_power_level = IEEE80211_UNSET_POWER_LEVEL;
 --- a/net/wireless/nl80211.c
 +++ b/net/wireless/nl80211.c
-@@ -395,6 +395,7 @@ static const struct nla_policy nl80211_p
-       [NL80211_ATTR_USER_PRIO] = { .type = NLA_U8 },
-       [NL80211_ATTR_ADMITTED_TIME] = { .type = NLA_U16 },
-       [NL80211_ATTR_SMPS_MODE] = { .type = NLA_U8 },
+@@ -400,6 +400,7 @@ static const struct nla_policy nl80211_p
+       [NL80211_ATTR_NETNS_FD] = { .type = NLA_U32 },
+       [NL80211_ATTR_SCHED_SCAN_DELAY] = { .type = NLA_U32 },
+       [NL80211_ATTR_REG_INDOOR] = { .type = NLA_FLAG },
 +      [NL80211_ATTR_WIPHY_ANTENNA_GAIN] = { .type = NLA_U32 },
  };
  
  /* policy for the key attributes */
-@@ -2184,6 +2185,20 @@ static int nl80211_set_wiphy(struct sk_b
+@@ -2207,6 +2208,20 @@ static int nl80211_set_wiphy(struct sk_b
                        return result;
        }
  
index cb6c477..0c4a8c9 100644 (file)
@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/ath/ath9k/ath9k.h
 +++ b/drivers/net/wireless/ath/ath9k/ath9k.h
-@@ -812,6 +812,9 @@ static inline int ath9k_dump_btcoex(stru
+@@ -814,6 +814,9 @@ static inline int ath9k_dump_btcoex(stru
  void ath_init_leds(struct ath_softc *sc);
  void ath_deinit_leds(struct ath_softc *sc);
  void ath_fill_led_pin(struct ath_softc *sc);
@@ -10,7 +10,7 @@
  #else
  static inline void ath_init_leds(struct ath_softc *sc)
  {
-@@ -952,6 +955,13 @@ void ath_ant_comb_scan(struct ath_softc 
+@@ -953,6 +956,13 @@ void ath_ant_comb_scan(struct ath_softc 
  
  #define ATH9K_NUM_CHANCTX  2 /* supports 2 operating channels */
  
@@ -24,7 +24,7 @@
  struct ath_softc {
        struct ieee80211_hw *hw;
        struct device *dev;
-@@ -1003,9 +1013,8 @@ struct ath_softc {
+@@ -1004,9 +1014,8 @@ struct ath_softc {
        spinlock_t chan_lock;
  
  #ifdef CPTCFG_MAC80211_LEDS
  #ifdef CPTCFG_ATH9K_DEBUGFS
 --- a/drivers/net/wireless/ath/ath9k/gpio.c
 +++ b/drivers/net/wireless/ath/ath9k/gpio.c
-@@ -24,40 +24,102 @@
+@@ -24,45 +24,102 @@
  static void ath_led_brightness(struct led_classdev *led_cdev,
                               enum led_brightness brightness)
  {
 -      struct ath_softc *sc = container_of(led_cdev, struct ath_softc, led_cdev);
--      ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, (brightness == LED_OFF));
+-      u32 val = (brightness == LED_OFF);
 +      struct ath_led *led = container_of(led_cdev, struct ath_led, cdev);
 +      struct ath_softc *sc = led->sc;
-+
+-      if (sc->sc_ah->config.led_active_high)
+-              val = !val;
 +      ath9k_ps_wakeup(sc);
 +      ath9k_hw_set_gpio(sc->sc_ah, led->gpio->gpio,
&