+++ /dev/null
-From: Brian Norris <briannorris@chromium.org>
-Date: Thu, 19 Oct 2017 11:45:19 -0700
-Subject: [PATCH] ath10k: fix build errors with !CONFIG_PM
-
-Build errors have been reported with CONFIG_PM=n:
-
-drivers/net/wireless/ath/ath10k/pci.c:3416:8: error: implicit
-declaration of function 'ath10k_pci_suspend'
-[-Werror=implicit-function-declaration]
-
-drivers/net/wireless/ath/ath10k/pci.c:3428:8: error: implicit
-declaration of function 'ath10k_pci_resume'
-[-Werror=implicit-function-declaration]
-
-These are caused by the combination of the following two commits:
-
-6af1de2e4ec4 ("ath10k: mark PM functions as __maybe_unused")
-96378bd2c6cd ("ath10k: fix core PCI suspend when WoWLAN is supported but
-disabled")
-
-Both build fine on their own.
-
-But now that ath10k_pci_pm_{suspend,resume}() is compiled
-unconditionally, we should also compile ath10k_pci_{suspend,resume}()
-unconditionally.
-
-And drop the #ifdef around ath10k_pci_hif_{suspend,resume}() too; they
-are trivial (empty), so we're not saving much space by compiling them
-out. And the alternatives would be to sprinkle more __maybe_unused, or
-spread the #ifdef's further.
-
-Build tested with the following combinations:
-CONFIG_PM=y && CONFIG_PM_SLEEP=y
-CONFIG_PM=y && CONFIG_PM_SLEEP=n
-CONFIG_PM=n
-
-Fixes: 96378bd2c6cd ("ath10k: fix core PCI suspend when WoWLAN is supported but disabled")
-Fixes: 096ad2a15fd8 ("Merge branch 'ath-next'")
-Signed-off-by: Brian Norris <briannorris@chromium.org>
-Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
----
-
---- a/drivers/net/wireless/ath/ath10k/pci.c
-+++ b/drivers/net/wireless/ath/ath10k/pci.c
-@@ -2577,8 +2577,6 @@ void ath10k_pci_hif_power_down(struct at
- */
- }
-
--#ifdef CONFIG_PM
--
- static int ath10k_pci_hif_suspend(struct ath10k *ar)
- {
- /* Nothing to do; the important stuff is in the driver suspend. */
-@@ -2627,7 +2625,6 @@ static int ath10k_pci_resume(struct ath1
-
- return ret;
- }
--#endif
-
- static bool ath10k_pci_validate_cal(void *data, size_t size)
- {
-@@ -2782,10 +2779,8 @@ static const struct ath10k_hif_ops ath10
- .power_down = ath10k_pci_hif_power_down,
- .read32 = ath10k_pci_read32,
- .write32 = ath10k_pci_write32,
--#ifdef CONFIG_PM
- .suspend = ath10k_pci_hif_suspend,
- .resume = ath10k_pci_hif_resume,
--#endif
- .fetch_cal_eeprom = ath10k_pci_hif_fetch_cal_eeprom,
- };
-
--- /dev/null
+From: Brian Norris <briannorris@chromium.org>
+Date: Thu, 19 Oct 2017 11:45:19 -0700
+Subject: [PATCH] ath10k: fix build errors with !CONFIG_PM
+
+Build errors have been reported with CONFIG_PM=n:
+
+drivers/net/wireless/ath/ath10k/pci.c:3416:8: error: implicit
+declaration of function 'ath10k_pci_suspend'
+[-Werror=implicit-function-declaration]
+
+drivers/net/wireless/ath/ath10k/pci.c:3428:8: error: implicit
+declaration of function 'ath10k_pci_resume'
+[-Werror=implicit-function-declaration]
+
+These are caused by the combination of the following two commits:
+
+6af1de2e4ec4 ("ath10k: mark PM functions as __maybe_unused")
+96378bd2c6cd ("ath10k: fix core PCI suspend when WoWLAN is supported but
+disabled")
+
+Both build fine on their own.
+
+But now that ath10k_pci_pm_{suspend,resume}() is compiled
+unconditionally, we should also compile ath10k_pci_{suspend,resume}()
+unconditionally.
+
+And drop the #ifdef around ath10k_pci_hif_{suspend,resume}() too; they
+are trivial (empty), so we're not saving much space by compiling them
+out. And the alternatives would be to sprinkle more __maybe_unused, or
+spread the #ifdef's further.
+
+Build tested with the following combinations:
+CONFIG_PM=y && CONFIG_PM_SLEEP=y
+CONFIG_PM=y && CONFIG_PM_SLEEP=n
+CONFIG_PM=n
+
+Fixes: 96378bd2c6cd ("ath10k: fix core PCI suspend when WoWLAN is supported but disabled")
+Fixes: 096ad2a15fd8 ("Merge branch 'ath-next'")
+Signed-off-by: Brian Norris <briannorris@chromium.org>
+Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
+---
+
+--- a/drivers/net/wireless/ath/ath10k/pci.c
++++ b/drivers/net/wireless/ath/ath10k/pci.c
+@@ -2577,8 +2577,6 @@ void ath10k_pci_hif_power_down(struct at
+ */
+ }
+
+-#ifdef CONFIG_PM
+-
+ static int ath10k_pci_hif_suspend(struct ath10k *ar)
+ {
+ /* Nothing to do; the important stuff is in the driver suspend. */
+@@ -2627,7 +2625,6 @@ static int ath10k_pci_resume(struct ath1
+
+ return ret;
+ }
+-#endif
+
+ static bool ath10k_pci_validate_cal(void *data, size_t size)
+ {
+@@ -2782,10 +2779,8 @@ static const struct ath10k_hif_ops ath10
+ .power_down = ath10k_pci_hif_power_down,
+ .read32 = ath10k_pci_read32,
+ .write32 = ath10k_pci_write32,
+-#ifdef CONFIG_PM
+ .suspend = ath10k_pci_hif_suspend,
+ .resume = ath10k_pci_hif_resume,
+-#endif
+ .fetch_cal_eeprom = ath10k_pci_hif_fetch_cal_eeprom,
+ };
+
+++ /dev/null
-From: Johannes Berg <johannes.berg@intel.com>
-Date: Mon, 20 Nov 2017 17:01:44 +0100
-Subject: [PATCH] mac80211: properly free requested-but-not-started TX agg
- sessions
-
-When deleting a station or otherwise tearing down all aggregation
-sessions, make sure to delete requested but not yet started ones,
-to avoid the following scenario:
-
- * session is requested, added to tid_start_tx[]
- * ieee80211_ba_session_work() runs, gets past BLOCK_BA check
- * ieee80211_sta_tear_down_BA_sessions() runs, locks &sta->ampdu_mlme.mtx,
- e.g. while deleting the station - deleting all active sessions
- * ieee80211_ba_session_work() continues since tear down flushes it, and
- calls ieee80211_tx_ba_session_handle_start() for the new session, arms
- the timer for it
- * station deletion continues to __cleanup_single_sta() and frees the
- session struct, while the timer is armed
-
-Reported-by: Fengguang Wu <fengguang.wu@intel.com>
-Signed-off-by: Johannes Berg <johannes.berg@intel.com>
----
-
---- a/net/mac80211/agg-tx.c
-+++ b/net/mac80211/agg-tx.c
-@@ -330,6 +330,11 @@ int ___ieee80211_stop_tx_ba_session(stru
-
- spin_lock_bh(&sta->lock);
-
-+ /* free struct pending for start, if present */
-+ tid_tx = sta->ampdu_mlme.tid_start_tx[tid];
-+ kfree(tid_tx);
-+ sta->ampdu_mlme.tid_start_tx[tid] = NULL;
-+
- tid_tx = rcu_dereference_protected_tid_tx(sta, tid);
- if (!tid_tx) {
- spin_unlock_bh(&sta->lock);
--- /dev/null
+From: Johannes Berg <johannes.berg@intel.com>
+Date: Mon, 20 Nov 2017 17:01:44 +0100
+Subject: [PATCH] mac80211: properly free requested-but-not-started TX agg
+ sessions
+
+When deleting a station or otherwise tearing down all aggregation
+sessions, make sure to delete requested but not yet started ones,
+to avoid the following scenario:
+
+ * session is requested, added to tid_start_tx[]
+ * ieee80211_ba_session_work() runs, gets past BLOCK_BA check
+ * ieee80211_sta_tear_down_BA_sessions() runs, locks &sta->ampdu_mlme.mtx,
+ e.g. while deleting the station - deleting all active sessions
+ * ieee80211_ba_session_work() continues since tear down flushes it, and
+ calls ieee80211_tx_ba_session_handle_start() for the new session, arms
+ the timer for it
+ * station deletion continues to __cleanup_single_sta() and frees the
+ session struct, while the timer is armed
+
+Reported-by: Fengguang Wu <fengguang.wu@intel.com>
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+---
+
+--- a/net/mac80211/agg-tx.c
++++ b/net/mac80211/agg-tx.c
+@@ -330,6 +330,11 @@ int ___ieee80211_stop_tx_ba_session(stru
+
+ spin_lock_bh(&sta->lock);
+
++ /* free struct pending for start, if present */
++ tid_tx = sta->ampdu_mlme.tid_start_tx[tid];
++ kfree(tid_tx);
++ sta->ampdu_mlme.tid_start_tx[tid] = NULL;
++
+ tid_tx = rcu_dereference_protected_tid_tx(sta, tid);
+ if (!tid_tx) {
+ spin_unlock_bh(&sta->lock);
+++ /dev/null
-From 9df7ddc3ed25b7d3473f117a0680b9418adb5753 Mon Sep 17 00:00:00 2001
-Message-Id: <9df7ddc3ed25b7d3473f117a0680b9418adb5753.1515610034.git.mschiffer@universe-factory.net>
-From: Matthias Schiffer <mschiffer@universe-factory.net>
-Date: Mon, 27 Nov 2017 18:56:22 +0100
-Subject: [PATCH 1/2] ath9k: move spectral scan support under a separate config
- symbol
-
-At the moment, spectral scan support, and with it RELAY, is always enabled
-with ATH9K[_HTC]_DEBUGFS. Spectral scan support is currently the only user
-of RELAY in ath9k, and it unconditionally reserves a relay channel.
-
-Having debugfs support in ath9k is often useful even on very small embedded
-routers, where we'd rather like to avoid the code size and RAM usage of the
-relay support.
-
-Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
-Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
----
- drivers/net/wireless/ath/ath9k/Kconfig | 14 ++++++++++----
- drivers/net/wireless/ath/ath9k/Makefile | 4 ++--
- drivers/net/wireless/ath/ath9k/common-spectral.h | 4 ++--
- 3 files changed, 14 insertions(+), 8 deletions(-)
-
---- a/drivers/net/wireless/ath/ath9k/Kconfig
-+++ b/drivers/net/wireless/ath/ath9k/Kconfig
-@@ -64,13 +64,12 @@ config ATH9K_DEBUGFS
- depends on ATH9K && DEBUG_FS
- select MAC80211_DEBUGFS
- select ATH9K_COMMON_DEBUG
-- depends on RELAY
- ---help---
- Say Y, if you need access to ath9k's statistics for
- interrupts, rate control, etc.
-
-- Also required for changing debug message flags at run time.
-- As well as access to the FFT/spectral data and TX99.
-+ Also required for changing debug message flags at run time and for
-+ TX99.
-
- config ATH9K_STATION_STATISTICS
- bool "Detailed station statistics"
-@@ -181,7 +180,6 @@ config ATH9K_HTC_DEBUGFS
- bool "Atheros ath9k_htc debugging"
- depends on ATH9K_HTC && DEBUG_FS
- select ATH9K_COMMON_DEBUG
-- depends on RELAY
- ---help---
- Say Y, if you need access to ath9k_htc's statistics.
- As well as access to the FFT/spectral data.
-@@ -197,3 +195,11 @@ config ATH9K_HWRNG
-
- Say Y, feeds the entropy directly from the WiFi driver to the input
- pool.
-+
-+config ATH9K_COMMON_SPECTRAL
-+ bool "Atheros ath9k/ath9k_htc spectral scan support"
-+ depends on ATH9K_DEBUGFS || ATH9K_HTC_DEBUGFS
-+ depends on RELAY
-+ default n
-+ ---help---
-+ Say Y to enable access to the FFT/spectral data via debugfs.
---- a/drivers/net/wireless/ath/ath9k/Makefile
-+++ b/drivers/net/wireless/ath/ath9k/Makefile
-@@ -61,8 +61,8 @@ ath9k_common-y:= common.o \
- common-init.o \
- common-beacon.o \
-
--ath9k_common-$(CPTCFG_ATH9K_COMMON_DEBUG) += common-debug.o \
-- common-spectral.o
-+ath9k_common-$(CPTCFG_ATH9K_COMMON_DEBUG) += common-debug.o
-+ath9k_common-$(CPTCFG_ATH9K_COMMON_SPECTRAL) += common-spectral.o
-
- ath9k_htc-y += htc_hst.o \
- hif_usb.o \
---- a/drivers/net/wireless/ath/ath9k/common-spectral.h
-+++ b/drivers/net/wireless/ath/ath9k/common-spectral.h
-@@ -151,7 +151,7 @@ static inline u8 spectral_bitmap_weight(
- return bins[0] & 0x3f;
- }
-
--#ifdef CPTCFG_ATH9K_COMMON_DEBUG
-+#ifdef CPTCFG_ATH9K_COMMON_SPECTRAL
- void ath9k_cmn_spectral_init_debug(struct ath_spec_scan_priv *spec_priv, struct dentry *debugfs_phy);
- void ath9k_cmn_spectral_deinit_debug(struct ath_spec_scan_priv *spec_priv);
-
-@@ -183,6 +183,6 @@ static inline int ath_cmn_process_fft(st
- {
- return 0;
- }
--#endif /* CPTCFG_ATH9K_COMMON_DEBUG */
-+#endif /* CPTCFG_ATH9K_COMMON_SPECTRAL */
-
- #endif /* SPECTRAL_H */
---- a/local-symbols
-+++ b/local-symbols
-@@ -116,6 +116,7 @@ ATH9K_PCOEM=
- ATH9K_HTC=
- ATH9K_HTC_DEBUGFS=
- ATH9K_HWRNG=
-+ATH9K_COMMON_SPECTRAL=
- CARL9170=
- CARL9170_LEDS=
- CARL9170_DEBUGFS=
+++ /dev/null
-From 42e01cb9cb109fb0bb4743f6c54d6aa67ac39b61 Mon Sep 17 00:00:00 2001
-Message-Id: <42e01cb9cb109fb0bb4743f6c54d6aa67ac39b61.1515610034.git.mschiffer@universe-factory.net>
-In-Reply-To: <9df7ddc3ed25b7d3473f117a0680b9418adb5753.1515610034.git.mschiffer@universe-factory.net>
-References: <9df7ddc3ed25b7d3473f117a0680b9418adb5753.1515610034.git.mschiffer@universe-factory.net>
-From: Matthias Schiffer <mschiffer@universe-factory.net>
-Date: Mon, 27 Nov 2017 18:56:23 +0100
-Subject: [PATCH 2/2] ath10k: move spectral scan support under a separate
- config symbol
-
-At the moment, spectral scan support, and with it RELAY, is always enabled
-with ATH10K_DEBUGFS. Spectral scan support is currently the only user of
-RELAY in ath10k, and it unconditionally reserves a relay channel.
-
-Having debugfs support in ath10k is often useful even on very small
-embedded routers, where we'd rather like to avoid the code size and RAM
-usage of the relay support. While ath10k-based devices usually have more
-resources than ath9k-based ones, it makes sense to keep the configuration
-symmetric to ath9k, so the same base kernel without RELAY can be used for
-both ath9k and ath10k hardware.
-
-Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
-Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
----
- drivers/net/wireless/ath/ath10k/Kconfig | 9 ++++++++-
- drivers/net/wireless/ath/ath10k/Makefile | 2 +-
- drivers/net/wireless/ath/ath10k/spectral.h | 4 ++--
- 3 files changed, 11 insertions(+), 4 deletions(-)
-
---- a/drivers/net/wireless/ath/ath10k/Kconfig
-+++ b/drivers/net/wireless/ath/ath10k/Kconfig
-@@ -51,12 +51,19 @@ config ATH10K_DEBUG
- config ATH10K_DEBUGFS
- bool "Atheros ath10k debugfs support"
- depends on ATH10K && DEBUG_FS
-- depends on RELAY
- ---help---
- Enabled debugfs support
-
- If unsure, say Y to make it easier to debug problems.
-
-+config ATH10K_SPECTRAL
-+ bool "Atheros ath10k spectral scan support"
-+ depends on ATH10K_DEBUGFS
-+ depends on RELAY
-+ default n
-+ ---help---
-+ Say Y to enable access to the FFT/spectral data via debugfs.
-+
- config ATH10K_TRACING
- depends on !KERNEL_3_4
- bool "Atheros ath10k tracing support"
---- a/drivers/net/wireless/ath/ath10k/Makefile
-+++ b/drivers/net/wireless/ath/ath10k/Makefile
-@@ -14,7 +14,7 @@ ath10k_core-y += mac.o \
- p2p.o \
- swap.o
-
--ath10k_core-$(CPTCFG_ATH10K_DEBUGFS) += spectral.o
-+ath10k_core-$(CPTCFG_ATH10K_SPECTRAL) += spectral.o
- ath10k_core-$(CPTCFG_NL80211_TESTMODE) += testmode.o
- ath10k_core-$(CPTCFG_ATH10K_TRACING) += trace.o
- ath10k_core-$(CPTCFG_ATH10K_THERMAL) += thermal.o
---- a/drivers/net/wireless/ath/ath10k/spectral.h
-+++ b/drivers/net/wireless/ath/ath10k/spectral.h
-@@ -44,7 +44,7 @@ enum ath10k_spectral_mode {
- SPECTRAL_MANUAL,
- };
-
--#ifdef CPTCFG_ATH10K_DEBUGFS
-+#ifdef CPTCFG_ATH10K_SPECTRAL
-
- int ath10k_spectral_process_fft(struct ath10k *ar,
- struct wmi_phyerr_ev_arg *phyerr,
-@@ -85,6 +85,6 @@ static inline void ath10k_spectral_destr
- {
- }
-
--#endif /* CPTCFG_ATH10K_DEBUGFS */
-+#endif /* CPTCFG_ATH10K_SPECTRAL */
-
- #endif /* SPECTRAL_H */
---- a/local-symbols
-+++ b/local-symbols
-@@ -140,6 +140,7 @@ ATH10K_SDIO=
- ATH10K_USB=
- ATH10K_DEBUG=
- ATH10K_DEBUGFS=
-+ATH10K_SPECTRAL=
- ATH10K_TRACING=
- ATH10K_DFS_CERTIFIED=
- WCN36XX=
--- /dev/null
+From 9df7ddc3ed25b7d3473f117a0680b9418adb5753 Mon Sep 17 00:00:00 2001
+Message-Id: <9df7ddc3ed25b7d3473f117a0680b9418adb5753.1515610034.git.mschiffer@universe-factory.net>
+From: Matthias Schiffer <mschiffer@universe-factory.net>
+Date: Mon, 27 Nov 2017 18:56:22 +0100
+Subject: [PATCH 1/2] ath9k: move spectral scan support under a separate config
+ symbol
+
+At the moment, spectral scan support, and with it RELAY, is always enabled
+with ATH9K[_HTC]_DEBUGFS. Spectral scan support is currently the only user
+of RELAY in ath9k, and it unconditionally reserves a relay channel.
+
+Having debugfs support in ath9k is often useful even on very small embedded
+routers, where we'd rather like to avoid the code size and RAM usage of the
+relay support.
+
+Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
+Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
+---
+ drivers/net/wireless/ath/ath9k/Kconfig | 14 ++++++++++----
+ drivers/net/wireless/ath/ath9k/Makefile | 4 ++--
+ drivers/net/wireless/ath/ath9k/common-spectral.h | 4 ++--
+ 3 files changed, 14 insertions(+), 8 deletions(-)
+
+--- a/drivers/net/wireless/ath/ath9k/Kconfig
++++ b/drivers/net/wireless/ath/ath9k/Kconfig
+@@ -64,13 +64,12 @@ config ATH9K_DEBUGFS
+ depends on ATH9K && DEBUG_FS
+ select MAC80211_DEBUGFS
+ select ATH9K_COMMON_DEBUG
+- depends on RELAY
+ ---help---
+ Say Y, if you need access to ath9k's statistics for
+ interrupts, rate control, etc.
+
+- Also required for changing debug message flags at run time.
+- As well as access to the FFT/spectral data and TX99.
++ Also required for changing debug message flags at run time and for
++ TX99.
+
+ config ATH9K_STATION_STATISTICS
+ bool "Detailed station statistics"
+@@ -181,7 +180,6 @@ config ATH9K_HTC_DEBUGFS
+ bool "Atheros ath9k_htc debugging"
+ depends on ATH9K_HTC && DEBUG_FS
+ select ATH9K_COMMON_DEBUG
+- depends on RELAY
+ ---help---
+ Say Y, if you need access to ath9k_htc's statistics.
+ As well as access to the FFT/spectral data.
+@@ -197,3 +195,11 @@ config ATH9K_HWRNG
+
+ Say Y, feeds the entropy directly from the WiFi driver to the input
+ pool.
++
++config ATH9K_COMMON_SPECTRAL
++ bool "Atheros ath9k/ath9k_htc spectral scan support"
++ depends on ATH9K_DEBUGFS || ATH9K_HTC_DEBUGFS
++ depends on RELAY
++ default n
++ ---help---
++ Say Y to enable access to the FFT/spectral data via debugfs.
+--- a/drivers/net/wireless/ath/ath9k/Makefile
++++ b/drivers/net/wireless/ath/ath9k/Makefile
+@@ -61,8 +61,8 @@ ath9k_common-y:= common.o \
+ common-init.o \
+ common-beacon.o \
+
+-ath9k_common-$(CPTCFG_ATH9K_COMMON_DEBUG) += common-debug.o \
+- common-spectral.o
++ath9k_common-$(CPTCFG_ATH9K_COMMON_DEBUG) += common-debug.o
++ath9k_common-$(CPTCFG_ATH9K_COMMON_SPECTRAL) += common-spectral.o
+
+ ath9k_htc-y += htc_hst.o \
+ hif_usb.o \
+--- a/drivers/net/wireless/ath/ath9k/common-spectral.h
++++ b/drivers/net/wireless/ath/ath9k/common-spectral.h
+@@ -151,7 +151,7 @@ static inline u8 spectral_bitmap_weight(
+ return bins[0] & 0x3f;
+ }
+
+-#ifdef CPTCFG_ATH9K_COMMON_DEBUG
++#ifdef CPTCFG_ATH9K_COMMON_SPECTRAL
+ void ath9k_cmn_spectral_init_debug(struct ath_spec_scan_priv *spec_priv, struct dentry *debugfs_phy);
+ void ath9k_cmn_spectral_deinit_debug(struct ath_spec_scan_priv *spec_priv);
+
+@@ -183,6 +183,6 @@ static inline int ath_cmn_process_fft(st
+ {
+ return 0;
+ }
+-#endif /* CPTCFG_ATH9K_COMMON_DEBUG */
++#endif /* CPTCFG_ATH9K_COMMON_SPECTRAL */
+
+ #endif /* SPECTRAL_H */
+--- a/local-symbols
++++ b/local-symbols
+@@ -116,6 +116,7 @@ ATH9K_PCOEM=
+ ATH9K_HTC=
+ ATH9K_HTC_DEBUGFS=
+ ATH9K_HWRNG=
++ATH9K_COMMON_SPECTRAL=
+ CARL9170=
+ CARL9170_LEDS=
+ CARL9170_DEBUGFS=
--- /dev/null
+From 42e01cb9cb109fb0bb4743f6c54d6aa67ac39b61 Mon Sep 17 00:00:00 2001
+Message-Id: <42e01cb9cb109fb0bb4743f6c54d6aa67ac39b61.1515610034.git.mschiffer@universe-factory.net>
+In-Reply-To: <9df7ddc3ed25b7d3473f117a0680b9418adb5753.1515610034.git.mschiffer@universe-factory.net>
+References: <9df7ddc3ed25b7d3473f117a0680b9418adb5753.1515610034.git.mschiffer@universe-factory.net>
+From: Matthias Schiffer <mschiffer@universe-factory.net>
+Date: Mon, 27 Nov 2017 18:56:23 +0100
+Subject: [PATCH 2/2] ath10k: move spectral scan support under a separate
+ config symbol
+
+At the moment, spectral scan support, and with it RELAY, is always enabled
+with ATH10K_DEBUGFS. Spectral scan support is currently the only user of
+RELAY in ath10k, and it unconditionally reserves a relay channel.
+
+Having debugfs support in ath10k is often useful even on very small
+embedded routers, where we'd rather like to avoid the code size and RAM
+usage of the relay support. While ath10k-based devices usually have more
+resources than ath9k-based ones, it makes sense to keep the configuration
+symmetric to ath9k, so the same base kernel without RELAY can be used for
+both ath9k and ath10k hardware.
+
+Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
+Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
+---
+ drivers/net/wireless/ath/ath10k/Kconfig | 9 ++++++++-
+ drivers/net/wireless/ath/ath10k/Makefile | 2 +-
+ drivers/net/wireless/ath/ath10k/spectral.h | 4 ++--
+ 3 files changed, 11 insertions(+), 4 deletions(-)
+
+--- a/drivers/net/wireless/ath/ath10k/Kconfig
++++ b/drivers/net/wireless/ath/ath10k/Kconfig
+@@ -51,12 +51,19 @@ config ATH10K_DEBUG
+ config ATH10K_DEBUGFS
+ bool "Atheros ath10k debugfs support"
+ depends on ATH10K && DEBUG_FS
+- depends on RELAY
+ ---help---
+ Enabled debugfs support
+
+ If unsure, say Y to make it easier to debug problems.
+
++config ATH10K_SPECTRAL
++ bool "Atheros ath10k spectral scan support"
++ depends on ATH10K_DEBUGFS
++ depends on RELAY
++ default n
++ ---help---
++ Say Y to enable access to the FFT/spectral data via debugfs.
++
+ config ATH10K_TRACING
+ depends on !KERNEL_3_4
+ bool "Atheros ath10k tracing support"
+--- a/drivers/net/wireless/ath/ath10k/Makefile
++++ b/drivers/net/wireless/ath/ath10k/Makefile
+@@ -14,7 +14,7 @@ ath10k_core-y += mac.o \
+ p2p.o \
+ swap.o
+
+-ath10k_core-$(CPTCFG_ATH10K_DEBUGFS) += spectral.o
++ath10k_core-$(CPTCFG_ATH10K_SPECTRAL) += spectral.o
+ ath10k_core-$(CPTCFG_NL80211_TESTMODE) += testmode.o
+ ath10k_core-$(CPTCFG_ATH10K_TRACING) += trace.o
+ ath10k_core-$(CPTCFG_ATH10K_THERMAL) += thermal.o
+--- a/drivers/net/wireless/ath/ath10k/spectral.h
++++ b/drivers/net/wireless/ath/ath10k/spectral.h
+@@ -44,7 +44,7 @@ enum ath10k_spectral_mode {
+ SPECTRAL_MANUAL,
+ };
+
+-#ifdef CPTCFG_ATH10K_DEBUGFS
++#ifdef CPTCFG_ATH10K_SPECTRAL
+
+ int ath10k_spectral_process_fft(struct ath10k *ar,
+ struct wmi_phyerr_ev_arg *phyerr,
+@@ -85,6 +85,6 @@ static inline void ath10k_spectral_destr
+ {
+ }
+
+-#endif /* CPTCFG_ATH10K_DEBUGFS */
++#endif /* CPTCFG_ATH10K_SPECTRAL */
+
+ #endif /* SPECTRAL_H */
+--- a/local-symbols
++++ b/local-symbols
+@@ -140,6 +140,7 @@ ATH10K_SDIO=
+ ATH10K_USB=
+ ATH10K_DEBUG=
+ ATH10K_DEBUGFS=
++ATH10K_SPECTRAL=
+ ATH10K_TRACING=
+ ATH10K_DFS_CERTIFIED=
+ WCN36XX=
+++ /dev/null
-From: Felix Fietkau <nbd@nbd.name>
-Date: Wed, 17 Jan 2018 11:11:17 +0100
-Subject: [PATCH] ath9k: discard undersized packets
-
-Sometimes the hardware will push small packets that trigger a WARN_ON
-in mac80211. Discard them early to avoid this issue.
-
-Reported-by: Stijn Tintel <stijn@linux-ipv6.be>
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/drivers/net/wireless/ath/ath9k/recv.c
-+++ b/drivers/net/wireless/ath/ath9k/recv.c
-@@ -826,9 +826,9 @@ static int ath9k_rx_skb_preprocess(struc
- sc->rx.discard_next = false;
-
- /*
-- * Discard zero-length packets.
-+ * Discard zero-length packets and packets smaller than an ACK
- */
-- if (!rx_stats->rs_datalen) {
-+ if (rx_stats->rs_datalen < 10) {
- RX_STAT_INC(rx_len_err);
- goto corrupt;
- }
--- /dev/null
+From: Felix Fietkau <nbd@nbd.name>
+Date: Wed, 17 Jan 2018 11:11:17 +0100
+Subject: [PATCH] ath9k: discard undersized packets
+
+Sometimes the hardware will push small packets that trigger a WARN_ON
+in mac80211. Discard them early to avoid this issue.
+
+Reported-by: Stijn Tintel <stijn@linux-ipv6.be>
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+---
+
+--- a/drivers/net/wireless/ath/ath9k/recv.c
++++ b/drivers/net/wireless/ath/ath9k/recv.c
+@@ -826,9 +826,9 @@ static int ath9k_rx_skb_preprocess(struc
+ sc->rx.discard_next = false;
+
+ /*
+- * Discard zero-length packets.
++ * Discard zero-length packets and packets smaller than an ACK
+ */
+- if (!rx_stats->rs_datalen) {
++ if (rx_stats->rs_datalen < 10) {
+ RX_STAT_INC(rx_len_err);
+ goto corrupt;
+ }
+++ /dev/null
-From: Johannes Berg <johannes.berg@intel.com>
-Date: Thu, 4 Jan 2018 15:51:53 +0100
-Subject: [PATCH] mac80211: mesh: drop frames appearing to be from us
-
-If there are multiple mesh stations with the same MAC address,
-they will both get confused and start throwing warnings.
-
-Obviously in this case nothing can actually work anyway, so just
-drop frames that look like they're from ourselves early on.
-
-Reported-by: Gui Iribarren <gui@altermundi.net>
-Signed-off-by: Johannes Berg <johannes.berg@intel.com>
----
-
---- a/net/mac80211/rx.c
-+++ b/net/mac80211/rx.c
-@@ -3632,6 +3632,8 @@ static bool ieee80211_accept_frame(struc
- }
- return true;
- case NL80211_IFTYPE_MESH_POINT:
-+ if (ether_addr_equal(sdata->vif.addr, hdr->addr2))
-+ return false;
- if (multicast)
- return true;
- return ether_addr_equal(sdata->vif.addr, hdr->addr1);
--- /dev/null
+From: Johannes Berg <johannes.berg@intel.com>
+Date: Thu, 4 Jan 2018 15:51:53 +0100
+Subject: [PATCH] mac80211: mesh: drop frames appearing to be from us
+
+If there are multiple mesh stations with the same MAC address,
+they will both get confused and start throwing warnings.
+
+Obviously in this case nothing can actually work anyway, so just
+drop frames that look like they're from ourselves early on.
+
+Reported-by: Gui Iribarren <gui@altermundi.net>
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+---
+
+--- a/net/mac80211/rx.c
++++ b/net/mac80211/rx.c
+@@ -3632,6 +3632,8 @@ static bool ieee80211_accept_frame(struc
+ }
+ return true;
+ case NL80211_IFTYPE_MESH_POINT:
++ if (ether_addr_equal(sdata->vif.addr, hdr->addr2))
++ return false;
+ if (multicast)
+ return true;
+ return ether_addr_equal(sdata->vif.addr, hdr->addr1);
+++ /dev/null
-From: Felix Fietkau <nbd@nbd.name>
-Date: Fri, 9 Feb 2018 19:46:54 +0100
-Subject: [PATCH] mac80211: round IEEE80211_TX_STATUS_HEADROOM up to multiple
- of 4
-
-This ensures that mac80211 allocated management frames are properly
-aligned, which makes copying them more efficient.
-For instance, mt76 uses iowrite32_copy to copy beacon frames to beacon
-template memory on the chip.
-Misaligned 32-bit accesses cause CPU exceptions on MIPS and should be
-avoided.
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/include/net/mac80211.h
-+++ b/include/net/mac80211.h
-@@ -4149,7 +4149,7 @@ void ieee80211_sta_uapsd_trigger(struct
- * The TX headroom reserved by mac80211 for its own tx_status functions.
- * This is enough for the radiotap header.
- */
--#define IEEE80211_TX_STATUS_HEADROOM 14
-+#define IEEE80211_TX_STATUS_HEADROOM ALIGN(14, 4)
-
- /**
- * ieee80211_sta_set_buffered - inform mac80211 about driver-buffered frames
--- /dev/null
+From: Felix Fietkau <nbd@nbd.name>
+Date: Fri, 9 Feb 2018 19:46:54 +0100
+Subject: [PATCH] mac80211: round IEEE80211_TX_STATUS_HEADROOM up to multiple
+ of 4
+
+This ensures that mac80211 allocated management frames are properly
+aligned, which makes copying them more efficient.
+For instance, mt76 uses iowrite32_copy to copy beacon frames to beacon
+template memory on the chip.
+Misaligned 32-bit accesses cause CPU exceptions on MIPS and should be
+avoided.
+
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+---
+
+--- a/include/net/mac80211.h
++++ b/include/net/mac80211.h
+@@ -4149,7 +4149,7 @@ void ieee80211_sta_uapsd_trigger(struct
+ * The TX headroom reserved by mac80211 for its own tx_status functions.
+ * This is enough for the radiotap header.
+ */
+-#define IEEE80211_TX_STATUS_HEADROOM 14
++#define IEEE80211_TX_STATUS_HEADROOM ALIGN(14, 4)
+
+ /**
+ * ieee80211_sta_set_buffered - inform mac80211 about driver-buffered frames
+++ /dev/null
-From: Felix Fietkau <nbd@nbd.name>
-Date: Fri, 23 Feb 2018 09:59:35 +0100
-Subject: [PATCH] mac80211: drop frames with unexpected DS bits from
- fast-rx to slow path
-
-Fixes rx for 4-addr packets in AP mode
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/net/mac80211/rx.c
-+++ b/net/mac80211/rx.c
-@@ -3928,7 +3928,7 @@ static bool ieee80211_invoke_fast_rx(str
- if ((hdr->frame_control & cpu_to_le16(IEEE80211_FCTL_FROMDS |
- IEEE80211_FCTL_TODS)) !=
- fast_rx->expected_ds_bits)
-- goto drop;
-+ return false;
-
- /* assign the key to drop unencrypted frames (later)
- * and strip the IV/MIC if necessary
--- /dev/null
+From: Felix Fietkau <nbd@nbd.name>
+Date: Fri, 23 Feb 2018 09:59:35 +0100
+Subject: [PATCH] mac80211: drop frames with unexpected DS bits from
+ fast-rx to slow path
+
+Fixes rx for 4-addr packets in AP mode
+
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+---
+
+--- a/net/mac80211/rx.c
++++ b/net/mac80211/rx.c
+@@ -3928,7 +3928,7 @@ static bool ieee80211_invoke_fast_rx(str
+ if ((hdr->frame_control & cpu_to_le16(IEEE80211_FCTL_FROMDS |
+ IEEE80211_FCTL_TODS)) !=
+ fast_rx->expected_ds_bits)
+- goto drop;
++ return false;
+
+ /* assign the key to drop unencrypted frames (later)
+ * and strip the IV/MIC if necessary
+++ /dev/null
-From: Felix Fietkau <nbd@nbd.name>
-Date: Fri, 23 Feb 2018 10:00:22 +0100
-Subject: [PATCH] mac80211: support AP 4-addr mode fast-rx
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/net/mac80211/rx.c
-+++ b/net/mac80211/rx.c
-@@ -3774,6 +3774,15 @@ void ieee80211_check_fast_rx(struct sta_
- !(sdata->flags & IEEE80211_SDATA_DONT_BRIDGE_PACKETS) &&
- (sdata->vif.type != NL80211_IFTYPE_AP_VLAN ||
- !sdata->u.vlan.sta);
-+
-+ if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN &&
-+ sdata->u.vlan.sta) {
-+ fastrx.expected_ds_bits |=
-+ cpu_to_le16(IEEE80211_FCTL_FROMDS);
-+ fastrx.sa_offs = offsetof(struct ieee80211_hdr, addr4);
-+ fastrx.internal_forward = 0;
-+ }
-+
- break;
- default:
- goto clear;
--- /dev/null
+From: Felix Fietkau <nbd@nbd.name>
+Date: Fri, 23 Feb 2018 10:00:22 +0100
+Subject: [PATCH] mac80211: support AP 4-addr mode fast-rx
+
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+---
+
+--- a/net/mac80211/rx.c
++++ b/net/mac80211/rx.c
+@@ -3774,6 +3774,15 @@ void ieee80211_check_fast_rx(struct sta_
+ !(sdata->flags & IEEE80211_SDATA_DONT_BRIDGE_PACKETS) &&
+ (sdata->vif.type != NL80211_IFTYPE_AP_VLAN ||
+ !sdata->u.vlan.sta);
++
++ if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN &&
++ sdata->u.vlan.sta) {
++ fastrx.expected_ds_bits |=
++ cpu_to_le16(IEEE80211_FCTL_FROMDS);
++ fastrx.sa_offs = offsetof(struct ieee80211_hdr, addr4);
++ fastrx.internal_forward = 0;
++ }
++
+ break;
+ default:
+ goto clear;
+++ /dev/null
-From: Felix Fietkau <nbd@nbd.name>
-Date: Fri, 23 Feb 2018 10:01:53 +0100
-Subject: [PATCH] mac80211: support fast-rx with incompatible PS
- capabilities when PS is disabled
-
-When powersave is disabled for the interface, we can do fast-rx anyway.
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/net/mac80211/cfg.c
-+++ b/net/mac80211/cfg.c
-@@ -2658,6 +2658,7 @@ static int ieee80211_set_power_mgmt(stru
-
- ieee80211_recalc_ps(local);
- ieee80211_recalc_ps_vif(sdata);
-+ ieee80211_check_fast_rx_iface(sdata);
-
- return 0;
- }
---- a/net/mac80211/rx.c
-+++ b/net/mac80211/rx.c
-@@ -3741,12 +3741,7 @@ void ieee80211_check_fast_rx(struct sta_
- /* 4-addr is harder to deal with, later maybe */
- if (sdata->u.mgd.use_4addr)
- goto clear;
-- /* software powersave is a huge mess, avoid all of it */
-- if (ieee80211_hw_check(&local->hw, PS_NULLFUNC_STACK))
-- goto clear;
-- if (ieee80211_hw_check(&local->hw, SUPPORTS_PS) &&
-- !ieee80211_hw_check(&local->hw, SUPPORTS_DYNAMIC_PS))
-- goto clear;
-+
- if (sta->sta.tdls) {
- fastrx.da_offs = offsetof(struct ieee80211_hdr, addr1);
- fastrx.sa_offs = offsetof(struct ieee80211_hdr, addr2);
-@@ -3758,6 +3753,16 @@ void ieee80211_check_fast_rx(struct sta_
- fastrx.expected_ds_bits =
- cpu_to_le16(IEEE80211_FCTL_FROMDS);
- }
-+
-+ if (!sdata->u.mgd.powersave)
-+ break;
-+
-+ /* software powersave is a huge mess, avoid all of it */
-+ if (ieee80211_hw_check(&local->hw, PS_NULLFUNC_STACK))
-+ goto clear;
-+ if (ieee80211_hw_check(&local->hw, SUPPORTS_PS) &&
-+ !ieee80211_hw_check(&local->hw, SUPPORTS_DYNAMIC_PS))
-+ goto clear;
- break;
- case NL80211_IFTYPE_AP_VLAN:
- case NL80211_IFTYPE_AP:
--- /dev/null
+From: Felix Fietkau <nbd@nbd.name>
+Date: Fri, 23 Feb 2018 10:01:53 +0100
+Subject: [PATCH] mac80211: support fast-rx with incompatible PS
+ capabilities when PS is disabled
+
+When powersave is disabled for the interface, we can do fast-rx anyway.
+
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+---
+
+--- a/net/mac80211/cfg.c
++++ b/net/mac80211/cfg.c
+@@ -2658,6 +2658,7 @@ static int ieee80211_set_power_mgmt(stru
+
+ ieee80211_recalc_ps(local);
+ ieee80211_recalc_ps_vif(sdata);
++ ieee80211_check_fast_rx_iface(sdata);
+
+ return 0;
+ }
+--- a/net/mac80211/rx.c
++++ b/net/mac80211/rx.c
+@@ -3741,12 +3741,7 @@ void ieee80211_check_fast_rx(struct sta_
+ /* 4-addr is harder to deal with, later maybe */
+ if (sdata->u.mgd.use_4addr)
+ goto clear;
+- /* software powersave is a huge mess, avoid all of it */
+- if (ieee80211_hw_check(&local->hw, PS_NULLFUNC_STACK))
+- goto clear;
+- if (ieee80211_hw_check(&local->hw, SUPPORTS_PS) &&
+- !ieee80211_hw_check(&local->hw, SUPPORTS_DYNAMIC_PS))
+- goto clear;
++
+ if (sta->sta.tdls) {
+ fastrx.da_offs = offsetof(struct ieee80211_hdr, addr1);
+ fastrx.sa_offs = offsetof(struct ieee80211_hdr, addr2);
+@@ -3758,6 +3753,16 @@ void ieee80211_check_fast_rx(struct sta_
+ fastrx.expected_ds_bits =
+ cpu_to_le16(IEEE80211_FCTL_FROMDS);
+ }
++
++ if (!sdata->u.mgd.powersave)
++ break;
++
++ /* software powersave is a huge mess, avoid all of it */
++ if (ieee80211_hw_check(&local->hw, PS_NULLFUNC_STACK))
++ goto clear;
++ if (ieee80211_hw_check(&local->hw, SUPPORTS_PS) &&
++ !ieee80211_hw_check(&local->hw, SUPPORTS_DYNAMIC_PS))
++ goto clear;
+ break;
+ case NL80211_IFTYPE_AP_VLAN:
+ case NL80211_IFTYPE_AP:
+++ /dev/null
-From: Felix Fietkau <nbd@nbd.name>
-Date: Fri, 23 Feb 2018 10:05:08 +0100
-Subject: [PATCH] mac80211: support station 4-addr mode fast-rx
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/net/mac80211/rx.c
-+++ b/net/mac80211/rx.c
-@@ -3738,10 +3738,6 @@ void ieee80211_check_fast_rx(struct sta_
-
- switch (sdata->vif.type) {
- case NL80211_IFTYPE_STATION:
-- /* 4-addr is harder to deal with, later maybe */
-- if (sdata->u.mgd.use_4addr)
-- goto clear;
--
- if (sta->sta.tdls) {
- fastrx.da_offs = offsetof(struct ieee80211_hdr, addr1);
- fastrx.sa_offs = offsetof(struct ieee80211_hdr, addr2);
-@@ -3754,6 +3750,13 @@ void ieee80211_check_fast_rx(struct sta_
- cpu_to_le16(IEEE80211_FCTL_FROMDS);
- }
-
-+ if (sdata->u.mgd.use_4addr && !sta->sta.tdls) {
-+ fastrx.expected_ds_bits |=
-+ cpu_to_le16(IEEE80211_FCTL_TODS);
-+ fastrx.da_offs = offsetof(struct ieee80211_hdr, addr3);
-+ fastrx.sa_offs = offsetof(struct ieee80211_hdr, addr4);
-+ }
-+
- if (!sdata->u.mgd.powersave)
- break;
-
--- /dev/null
+From: Felix Fietkau <nbd@nbd.name>
+Date: Fri, 23 Feb 2018 10:05:08 +0100
+Subject: [PATCH] mac80211: support station 4-addr mode fast-rx
+
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+---
+
+--- a/net/mac80211/rx.c
++++ b/net/mac80211/rx.c
+@@ -3738,10 +3738,6 @@ void ieee80211_check_fast_rx(struct sta_
+
+ switch (sdata->vif.type) {
+ case NL80211_IFTYPE_STATION:
+- /* 4-addr is harder to deal with, later maybe */
+- if (sdata->u.mgd.use_4addr)
+- goto clear;
+-
+ if (sta->sta.tdls) {
+ fastrx.da_offs = offsetof(struct ieee80211_hdr, addr1);
+ fastrx.sa_offs = offsetof(struct ieee80211_hdr, addr2);
+@@ -3754,6 +3750,13 @@ void ieee80211_check_fast_rx(struct sta_
+ cpu_to_le16(IEEE80211_FCTL_FROMDS);
+ }
+
++ if (sdata->u.mgd.use_4addr && !sta->sta.tdls) {
++ fastrx.expected_ds_bits |=
++ cpu_to_le16(IEEE80211_FCTL_TODS);
++ fastrx.da_offs = offsetof(struct ieee80211_hdr, addr3);
++ fastrx.sa_offs = offsetof(struct ieee80211_hdr, addr4);
++ }
++
+ if (!sdata->u.mgd.powersave)
+ break;
+
+++ /dev/null
-From: Felix Fietkau <nbd@nbd.name>
-Date: Mon, 26 Feb 2018 22:09:29 +0100
-Subject: [PATCH] mac80211: support A-MSDU in fast-rx
-
-Only works if the IV was stripped from packets. Create a smaller
-variant of ieee80211_rx_h_amsdu, which bypasses checks already done
-within the fast-rx context.
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/net/mac80211/rx.c
-+++ b/net/mac80211/rx.c
-@@ -2358,39 +2358,17 @@ ieee80211_deliver_skb(struct ieee80211_r
- }
-
- static ieee80211_rx_result debug_noinline
--ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx)
-+__ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx, u8 data_offset)
- {
- struct net_device *dev = rx->sdata->dev;
- struct sk_buff *skb = rx->skb;
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
- __le16 fc = hdr->frame_control;
- struct sk_buff_head frame_list;
-- struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb);
- struct ethhdr ethhdr;
- const u8 *check_da = ethhdr.h_dest, *check_sa = ethhdr.h_source;
-
-- if (unlikely(!ieee80211_is_data(fc)))
-- return RX_CONTINUE;
--
-- if (unlikely(!ieee80211_is_data_present(fc)))
-- return RX_DROP_MONITOR;
--
-- if (!(status->rx_flags & IEEE80211_RX_AMSDU))
-- return RX_CONTINUE;
--
- if (unlikely(ieee80211_has_a4(hdr->frame_control))) {
-- switch (rx->sdata->vif.type) {
-- case NL80211_IFTYPE_AP_VLAN:
-- if (!rx->sdata->u.vlan.sta)
-- return RX_DROP_UNUSABLE;
-- break;
-- case NL80211_IFTYPE_STATION:
-- if (!rx->sdata->u.mgd.use_4addr)
-- return RX_DROP_UNUSABLE;
-- break;
-- default:
-- return RX_DROP_UNUSABLE;
-- }
- check_da = NULL;
- check_sa = NULL;
- } else switch (rx->sdata->vif.type) {
-@@ -2410,15 +2388,13 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx
- break;
- }
-
-- if (is_multicast_ether_addr(hdr->addr1))
-- return RX_DROP_UNUSABLE;
--
- skb->dev = dev;
- __skb_queue_head_init(&frame_list);
-
- if (ieee80211_data_to_8023_exthdr(skb, ðhdr,
- rx->sdata->vif.addr,
-- rx->sdata->vif.type))
-+ rx->sdata->vif.type,
-+ data_offset))
- return RX_DROP_UNUSABLE;
-
- ieee80211_amsdu_to_8023s(skb, &frame_list, dev->dev_addr,
-@@ -2440,6 +2416,44 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx
- return RX_QUEUED;
- }
-
-+static ieee80211_rx_result debug_noinline
-+ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx)
-+{
-+ struct sk_buff *skb = rx->skb;
-+ struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
-+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
-+ __le16 fc = hdr->frame_control;
-+
-+ if (!(status->rx_flags & IEEE80211_RX_AMSDU))
-+ return RX_CONTINUE;
-+
-+ if (unlikely(!ieee80211_is_data(fc)))
-+ return RX_CONTINUE;
-+
-+ if (unlikely(!ieee80211_is_data_present(fc)))
-+ return RX_DROP_MONITOR;
-+
-+ if (unlikely(ieee80211_has_a4(hdr->frame_control))) {
-+ switch (rx->sdata->vif.type) {
-+ case NL80211_IFTYPE_AP_VLAN:
-+ if (!rx->sdata->u.vlan.sta)
-+ return RX_DROP_UNUSABLE;
-+ break;
-+ case NL80211_IFTYPE_STATION:
-+ if (!rx->sdata->u.mgd.use_4addr)
-+ return RX_DROP_UNUSABLE;
-+ break;
-+ default:
-+ return RX_DROP_UNUSABLE;
-+ }
-+ }
-+
-+ if (is_multicast_ether_addr(hdr->addr1))
-+ return RX_DROP_UNUSABLE;
-+
-+ return __ieee80211_rx_h_amsdu(rx, 0);
-+}
-+
- #ifdef CPTCFG_MAC80211_MESH
- static ieee80211_rx_result
- ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
-@@ -3889,7 +3903,8 @@ static bool ieee80211_invoke_fast_rx(str
- struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
- struct sta_info *sta = rx->sta;
- int orig_len = skb->len;
-- int snap_offs = ieee80211_hdrlen(hdr->frame_control);
-+ int hdrlen = ieee80211_hdrlen(hdr->frame_control);
-+ int snap_offs = hdrlen;
- struct {
- u8 snap[sizeof(rfc1042_header)];
- __be16 proto;
-@@ -3920,10 +3935,6 @@ static bool ieee80211_invoke_fast_rx(str
- (status->flag & FAST_RX_CRYPT_FLAGS) != FAST_RX_CRYPT_FLAGS)
- return false;
-
-- /* we don't deal with A-MSDU deaggregation here */
-- if (status->rx_flags & IEEE80211_RX_AMSDU)
-- return false;
--
- if (unlikely(!ieee80211_is_data_present(hdr->frame_control)))
- return false;
-
-@@ -3955,21 +3966,24 @@ static bool ieee80211_invoke_fast_rx(str
- snap_offs += IEEE80211_CCMP_HDR_LEN;
- }
-
-- if (!pskb_may_pull(skb, snap_offs + sizeof(*payload)))
-- goto drop;
-- payload = (void *)(skb->data + snap_offs);
-+ if (!(status->rx_flags & IEEE80211_RX_AMSDU)) {
-+ if (!pskb_may_pull(skb, snap_offs + sizeof(*payload)))
-+ goto drop;
-
-- if (!ether_addr_equal(payload->snap, fast_rx->rfc1042_hdr))
-- return false;
-+ payload = (void *)(skb->data + snap_offs);
-
-- /* Don't handle these here since they require special code.
-- * Accept AARP and IPX even though they should come with a
-- * bridge-tunnel header - but if we get them this way then
-- * there's little point in discarding them.
-- */
-- if (unlikely(payload->proto == cpu_to_be16(ETH_P_TDLS) ||
-- payload->proto == fast_rx->control_port_protocol))
-- return false;
-+ if (!ether_addr_equal(payload->snap, fast_rx->rfc1042_hdr))
-+ return false;
-+
-+ /* Don't handle these here since they require special code.
-+ * Accept AARP and IPX even though they should come with a
-+ * bridge-tunnel header - but if we get them this way then
-+ * there's little point in discarding them.
-+ */
-+ if (unlikely(payload->proto == cpu_to_be16(ETH_P_TDLS) ||
-+ payload->proto == fast_rx->control_port_protocol))
-+ return false;
-+ }
-
- /* after this point, don't punt to the slowpath! */
-
-@@ -3983,12 +3997,6 @@ static bool ieee80211_invoke_fast_rx(str
- }
-
- /* statistics part of ieee80211_rx_h_sta_process() */
-- stats->last_rx = jiffies;
-- stats->last_rate = sta_stats_encode_rate(status);
--
-- stats->fragments++;
-- stats->packets++;
--
- if (!(status->flag & RX_FLAG_NO_SIGNAL_VAL)) {
- stats->last_signal = status->signal;
- if (!fast_rx->uses_rss)
-@@ -4017,6 +4025,20 @@ static bool ieee80211_invoke_fast_rx(str
- if (rx->key && !ieee80211_has_protected(hdr->frame_control))
- goto drop;
-
-+ if (status->rx_flags & IEEE80211_RX_AMSDU) {
-+ if (__ieee80211_rx_h_amsdu(rx, snap_offs - hdrlen) !=
-+ RX_QUEUED)
-+ goto drop;
-+
-+ return true;
-+ }
-+
-+ stats->last_rx = jiffies;
-+ stats->last_rate = sta_stats_encode_rate(status);
-+
-+ stats->fragments++;
-+ stats->packets++;
-+
- /* do the header conversion - first grab the addresses */
- ether_addr_copy(addrs.da, skb->data + fast_rx->da_offs);
- ether_addr_copy(addrs.sa, skb->data + fast_rx->sa_offs);
---- a/include/net/cfg80211.h
-+++ b/include/net/cfg80211.h
-@@ -4331,10 +4331,12 @@ unsigned int ieee80211_get_mesh_hdrlen(s
- * of it being pushed into the SKB
- * @addr: the device MAC address
- * @iftype: the virtual interface type
-+ * @data_offset: offset of payload after the 802.11 header
- * Return: 0 on success. Non-zero on error.
- */
- int ieee80211_data_to_8023_exthdr(struct sk_buff *skb, struct ethhdr *ehdr,
-- const u8 *addr, enum nl80211_iftype iftype);
-+ const u8 *addr, enum nl80211_iftype iftype,
-+ u8 data_offset);
-
- /**
- * ieee80211_data_to_8023 - convert an 802.11 data frame to 802.3
-@@ -4346,7 +4348,7 @@ int ieee80211_data_to_8023_exthdr(struct
- static inline int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr,
- enum nl80211_iftype iftype)
- {
-- return ieee80211_data_to_8023_exthdr(skb, NULL, addr, iftype);
-+ return ieee80211_data_to_8023_exthdr(skb, NULL, addr, iftype, 0);
- }
-
- /**
---- a/net/wireless/util.c
-+++ b/net/wireless/util.c
-@@ -419,7 +419,8 @@ unsigned int ieee80211_get_mesh_hdrlen(s
- EXPORT_SYMBOL(ieee80211_get_mesh_hdrlen);
-
- int ieee80211_data_to_8023_exthdr(struct sk_buff *skb, struct ethhdr *ehdr,
-- const u8 *addr, enum nl80211_iftype iftype)
-+ const u8 *addr, enum nl80211_iftype iftype,
-+ u8 data_offset)
- {
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
- struct {
-@@ -433,7 +434,7 @@ int ieee80211_data_to_8023_exthdr(struct
- if (unlikely(!ieee80211_is_data_present(hdr->frame_control)))
- return -1;
-
-- hdrlen = ieee80211_hdrlen(hdr->frame_control);
-+ hdrlen = ieee80211_hdrlen(hdr->frame_control) + data_offset;
- if (skb->len < hdrlen + 8)
- return -1;
-
--- /dev/null
+From: Felix Fietkau <nbd@nbd.name>
+Date: Mon, 26 Feb 2018 22:09:29 +0100
+Subject: [PATCH] mac80211: support A-MSDU in fast-rx
+
+Only works if the IV was stripped from packets. Create a smaller
+variant of ieee80211_rx_h_amsdu, which bypasses checks already done
+within the fast-rx context.
+
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+---
+
+--- a/net/mac80211/rx.c
++++ b/net/mac80211/rx.c
+@@ -2358,39 +2358,17 @@ ieee80211_deliver_skb(struct ieee80211_r
+ }
+
+ static ieee80211_rx_result debug_noinline
+-ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx)
++__ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx, u8 data_offset)
+ {
+ struct net_device *dev = rx->sdata->dev;
+ struct sk_buff *skb = rx->skb;
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+ __le16 fc = hdr->frame_control;
+ struct sk_buff_head frame_list;
+- struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb);
+ struct ethhdr ethhdr;
+ const u8 *check_da = ethhdr.h_dest, *check_sa = ethhdr.h_source;
+
+- if (unlikely(!ieee80211_is_data(fc)))
+- return RX_CONTINUE;
+-
+- if (unlikely(!ieee80211_is_data_present(fc)))
+- return RX_DROP_MONITOR;
+-
+- if (!(status->rx_flags & IEEE80211_RX_AMSDU))
+- return RX_CONTINUE;
+-
+ if (unlikely(ieee80211_has_a4(hdr->frame_control))) {
+- switch (rx->sdata->vif.type) {
+- case NL80211_IFTYPE_AP_VLAN:
+- if (!rx->sdata->u.vlan.sta)
+- return RX_DROP_UNUSABLE;
+- break;
+- case NL80211_IFTYPE_STATION:
+- if (!rx->sdata->u.mgd.use_4addr)
+- return RX_DROP_UNUSABLE;
+- break;
+- default:
+- return RX_DROP_UNUSABLE;
+- }
+ check_da = NULL;
+ check_sa = NULL;
+ } else switch (rx->sdata->vif.type) {
+@@ -2410,15 +2388,13 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx
+ break;
+ }
+
+- if (is_multicast_ether_addr(hdr->addr1))
+- return RX_DROP_UNUSABLE;
+-
+ skb->dev = dev;
+ __skb_queue_head_init(&frame_list);
+
+ if (ieee80211_data_to_8023_exthdr(skb, ðhdr,
+ rx->sdata->vif.addr,
+- rx->sdata->vif.type))
++ rx->sdata->vif.type,
++ data_offset))
+ return RX_DROP_UNUSABLE;
+
+ ieee80211_amsdu_to_8023s(skb, &frame_list, dev->dev_addr,
+@@ -2440,6 +2416,44 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx
+ return RX_QUEUED;
+ }
+
++static ieee80211_rx_result debug_noinline
++ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx)
++{
++ struct sk_buff *skb = rx->skb;
++ struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
++ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
++ __le16 fc = hdr->frame_control;
++
++ if (!(status->rx_flags & IEEE80211_RX_AMSDU))
++ return RX_CONTINUE;
++
++ if (unlikely(!ieee80211_is_data(fc)))
++ return RX_CONTINUE;
++
++ if (unlikely(!ieee80211_is_data_present(fc)))
++ return RX_DROP_MONITOR;
++
++ if (unlikely(ieee80211_has_a4(hdr->frame_control))) {
++ switch (rx->sdata->vif.type) {
++ case NL80211_IFTYPE_AP_VLAN:
++ if (!rx->sdata->u.vlan.sta)
++ return RX_DROP_UNUSABLE;
++ break;
++ case NL80211_IFTYPE_STATION:
++ if (!rx->sdata->u.mgd.use_4addr)
++ return RX_DROP_UNUSABLE;
++ break;
++ default:
++ return RX_DROP_UNUSABLE;
++ }
++ }
++
++ if (is_multicast_ether_addr(hdr->addr1))
++ return RX_DROP_UNUSABLE;
++
++ return __ieee80211_rx_h_amsdu(rx, 0);
++}
++
+ #ifdef CPTCFG_MAC80211_MESH
+ static ieee80211_rx_result
+ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
+@@ -3889,7 +3903,8 @@ static bool ieee80211_invoke_fast_rx(str
+ struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
+ struct sta_info *sta = rx->sta;
+ int orig_len = skb->len;
+- int snap_offs = ieee80211_hdrlen(hdr->frame_control);
++ int hdrlen = ieee80211_hdrlen(hdr->frame_control);
++ int snap_offs = hdrlen;
+ struct {
+ u8 snap[sizeof(rfc1042_header)];
+ __be16 proto;
+@@ -3920,10 +3935,6 @@ static bool ieee80211_invoke_fast_rx(str
+ (status->flag & FAST_RX_CRYPT_FLAGS) != FAST_RX_CRYPT_FLAGS)
+ return false;
+
+- /* we don't deal with A-MSDU deaggregation here */
+- if (status->rx_flags & IEEE80211_RX_AMSDU)
+- return false;
+-
+ if (unlikely(!ieee80211_is_data_present(hdr->frame_control)))
+ return false;
+
+@@ -3955,21 +3966,24 @@ static bool ieee80211_invoke_fast_rx(str
+ snap_offs += IEEE80211_CCMP_HDR_LEN;
+ }
+
+- if (!pskb_may_pull(skb, snap_offs + sizeof(*payload)))
+- goto drop;
+- payload = (void *)(skb->data + snap_offs);
++ if (!(status->rx_flags & IEEE80211_RX_AMSDU)) {
++ if (!pskb_may_pull(skb, snap_offs + sizeof(*payload)))
++ goto drop;
+
+- if (!ether_addr_equal(payload->snap, fast_rx->rfc1042_hdr))
+- return false;
++ payload = (void *)(skb->data + snap_offs);
+
+- /* Don't handle these here since they require special code.
+- * Accept AARP and IPX even though they should come with a
+- * bridge-tunnel header - but if we get them this way then
+- * there's little point in discarding them.
+- */
+- if (unlikely(payload->proto == cpu_to_be16(ETH_P_TDLS) ||
+- payload->proto == fast_rx->control_port_protocol))
+- return false;
++ if (!ether_addr_equal(payload->snap, fast_rx->rfc1042_hdr))
++ return false;
++
++ /* Don't handle these here since they require special code.
++ * Accept AARP and IPX even though they should come with a
++ * bridge-tunnel header - but if we get them this way then
++ * there's little point in discarding them.
++ */
++ if (unlikely(payload->proto == cpu_to_be16(ETH_P_TDLS) ||
++ payload->proto == fast_rx->control_port_protocol))
++ return false;
++ }
+
+ /* after this point, don't punt to the slowpath! */
+
+@@ -3983,12 +3997,6 @@ static bool ieee80211_invoke_fast_rx(str
+ }
+
+ /* statistics part of ieee80211_rx_h_sta_process() */
+- stats->last_rx = jiffies;
+- stats->last_rate = sta_stats_encode_rate(status);
+-
+- stats->fragments++;
+- stats->packets++;
+-
+ if (!(status->flag & RX_FLAG_NO_SIGNAL_VAL)) {
+ stats->last_signal = status->signal;
+ if (!fast_rx->uses_rss)
+@@ -4017,6 +4025,20 @@ static bool ieee80211_invoke_fast_rx(str
+ if (rx->key && !ieee80211_has_protected(hdr->frame_control))
+ goto drop;
+
++ if (status->rx_flags & IEEE80211_RX_AMSDU) {
++ if (__ieee80211_rx_h_amsdu(rx, snap_offs - hdrlen) !=
++ RX_QUEUED)
++ goto drop;
++
++ return true;
++ }
++
++ stats->last_rx = jiffies;
++ stats->last_rate = sta_stats_encode_rate(status);
++
++ stats->fragments++;
++ stats->packets++;
++
+ /* do the header conversion - first grab the addresses */
+ ether_addr_copy(addrs.da, skb->data + fast_rx->da_offs);
+ ether_addr_copy(addrs.sa, skb->data + fast_rx->sa_offs);
+--- a/include/net/cfg80211.h
++++ b/include/net/cfg80211.h
+@@ -4331,10 +4331,12 @@ unsigned int ieee80211_get_mesh_hdrlen(s
+ * of it being pushed into the SKB
+ * @addr: the device MAC address
+ * @iftype: the virtual interface type
++ * @data_offset: offset of payload after the 802.11 header
+ * Return: 0 on success. Non-zero on error.
+ */
+ int ieee80211_data_to_8023_exthdr(struct sk_buff *skb, struct ethhdr *ehdr,
+- const u8 *addr, enum nl80211_iftype iftype);
++ const u8 *addr, enum nl80211_iftype iftype,
++ u8 data_offset);
+
+ /**
+ * ieee80211_data_to_8023 - convert an 802.11 data frame to 802.3
+@@ -4346,7 +4348,7 @@ int ieee80211_data_to_8023_exthdr(struct
+ static inline int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr,
+ enum nl80211_iftype iftype)
+ {
+- return ieee80211_data_to_8023_exthdr(skb, NULL, addr, iftype);
++ return ieee80211_data_to_8023_exthdr(skb, NULL, addr, iftype, 0);
+ }
+
+ /**
+--- a/net/wireless/util.c
++++ b/net/wireless/util.c
+@@ -419,7 +419,8 @@ unsigned int ieee80211_get_mesh_hdrlen(s
+ EXPORT_SYMBOL(ieee80211_get_mesh_hdrlen);
+
+ int ieee80211_data_to_8023_exthdr(struct sk_buff *skb, struct ethhdr *ehdr,
+- const u8 *addr, enum nl80211_iftype iftype)
++ const u8 *addr, enum nl80211_iftype iftype,
++ u8 data_offset)
+ {
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+ struct {
+@@ -433,7 +434,7 @@ int ieee80211_data_to_8023_exthdr(struct
+ if (unlikely(!ieee80211_is_data_present(hdr->frame_control)))
+ return -1;
+
+- hdrlen = ieee80211_hdrlen(hdr->frame_control);
++ hdrlen = ieee80211_hdrlen(hdr->frame_control) + data_offset;
+ if (skb->len < hdrlen + 8)
+ return -1;
+