mac80211: ath10k: add tags for upstreamed patches
authorNick Hainke <vincent@systemli.org>
Sun, 6 Nov 2022 14:14:58 +0000 (15:14 +0100)
committerChristian Marangi <ansuelsmth@gmail.com>
Wed, 9 Nov 2022 16:07:42 +0000 (17:07 +0100)
Add tags to already upstreamed patches.

Signed-off-by: Nick Hainke <vincent@systemli.org>
12 files changed:
package/kernel/mac80211/patches/ath10k/081-01-ath10k-improve-tx-status-reporting.patch [deleted file]
package/kernel/mac80211/patches/ath10k/081-01-v6.0-ath10k-improve-tx-status-reporting.patch [new file with mode: 0644]
package/kernel/mac80211/patches/ath10k/081-02-ath10k-turn-rawmode-into-frame-mode.patch [deleted file]
package/kernel/mac80211/patches/ath10k/081-02-v6.0-ath10k-turn-rawmode-into-frame-mode.patch [new file with mode: 0644]
package/kernel/mac80211/patches/ath10k/081-03-ath10k-htt-tx-do-not-interpret-Eth-frames-as-WiFi.patch [deleted file]
package/kernel/mac80211/patches/ath10k/081-03-v6.0-ath10k-htt-tx-do-not-interpret-Eth-frames-as-WiFi.patch [new file with mode: 0644]
package/kernel/mac80211/patches/ath10k/081-04-ath10k-add-encapsulation-offloading-support.patch [deleted file]
package/kernel/mac80211/patches/ath10k/081-04-v6.0-ath10k-add-encapsulation-offloading-support.patch [new file with mode: 0644]
package/kernel/mac80211/patches/ath10k/100-ath10k-support-bus-and-device-specific-API-1-BDF-sel.patch [deleted file]
package/kernel/mac80211/patches/ath10k/100-v5.19-ath10k-support-bus-and-device-specific-API-1-BDF-sel.patch [new file with mode: 0644]
package/kernel/mac80211/patches/ath10k/120-ath10k-fetch-calibration-data-via-nvmem-subsystem.patch [deleted file]
package/kernel/mac80211/patches/ath10k/120-v5.17-ath10k-fetch-calibration-data-via-nvmem-subsystem.patch [new file with mode: 0644]

diff --git a/package/kernel/mac80211/patches/ath10k/081-01-ath10k-improve-tx-status-reporting.patch b/package/kernel/mac80211/patches/ath10k/081-01-ath10k-improve-tx-status-reporting.patch
deleted file mode 100644 (file)
index c024850..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-From 2587d5198aa5adcbd8896aae4a2404dc13d48637 Mon Sep 17 00:00:00 2001
-From: Sergey Ryazanov <ryazanov.s.a@gmail.com>
-Date: Wed, 18 May 2022 10:27:26 +0300
-Subject: ath10k: improve tx status reporting
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-We use ieee80211_tx_status() to report each completed tx frame.
-Internally, this function calls sta_info_get_by_addrs(), what has a
-couple of drawbacks:
-1. additional station lookup causes a performance degradation;
-2. mac80211 can not properly account Ethernet encapsulated frames due
-   to the inability to properly determine the destination (station) MAC
-   address since ieee80211_tx_status() assumes the frame has a 802.11
-   header.
-
-The latter is especially destructive if we want to use hardware frames
-encapsulation.
-
-To fix both of these issues, replace ieee80211_tx_status() with
-ieee80211_tx_status_ext() call and feed it station pointer from the tx
-queue associated with the transmitted frame.
-
-Tested-on: QCA9888 hw2.0 PCI 10.4-3.9.0.2-00131
-Tested-on: QCA6174 hw3.2 PCI WLAN.RM.4.4.1-00157-QCARMSWPZ-1
-
-Signed-off-by: Sergey Ryazanov <ryazanov.s.a@gmail.com>
-Tested-by: Oldřich Jedlička <oldium.pro@gmail.com> # TP-Link Archer C7 v4 & v5 (QCA9563 + QCA9880)
-Tested-by: Edward Matijevic <motolav@gmail.com> # TP-Link Archer C2600 (IPQ8064 + QCA9980 10.4.1.00030-1)
-Tested-by: Edward Matijevic <motolav@gmail.com> # QCA9377 PCI in Sta mode
-Tested-by: Zhijun You <hujy652@gmail.com> # NETGEAR R7800 (QCA9984 10.4-3.9.0.2-00159)
-Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
-Link: https://lore.kernel.org/r/20220516032519.29831-2-ryazanov.s.a@gmail.com
----
- drivers/net/wireless/ath/ath10k/txrx.c | 15 ++++++++++++++-
- 1 file changed, 14 insertions(+), 1 deletion(-)
-
---- a/drivers/net/wireless/ath/ath10k/txrx.c
-+++ b/drivers/net/wireless/ath/ath10k/txrx.c
-@@ -43,6 +43,7 @@ out:
- int ath10k_txrx_tx_unref(struct ath10k_htt *htt,
-                        const struct htt_tx_done *tx_done)
- {
-+      struct ieee80211_tx_status status;
-       struct ath10k *ar = htt->ar;
-       struct device *dev = ar->dev;
-       struct ieee80211_tx_info *info;
-@@ -128,7 +129,19 @@ int ath10k_txrx_tx_unref(struct ath10k_h
-               info->status.is_valid_ack_signal = true;
-       }
--      ieee80211_tx_status(htt->ar->hw, msdu);
-+      memset(&status, 0, sizeof(status));
-+      status.skb = msdu;
-+      status.info = info;
-+
-+      rcu_read_lock();
-+
-+      if (txq)
-+              status.sta = txq->sta;
-+
-+      ieee80211_tx_status_ext(htt->ar->hw, &status);
-+
-+      rcu_read_unlock();
-+
-       /* we do not own the msdu anymore */
-       return 0;
diff --git a/package/kernel/mac80211/patches/ath10k/081-01-v6.0-ath10k-improve-tx-status-reporting.patch b/package/kernel/mac80211/patches/ath10k/081-01-v6.0-ath10k-improve-tx-status-reporting.patch
new file mode 100644 (file)
index 0000000..c024850
--- /dev/null
@@ -0,0 +1,69 @@
+From 2587d5198aa5adcbd8896aae4a2404dc13d48637 Mon Sep 17 00:00:00 2001
+From: Sergey Ryazanov <ryazanov.s.a@gmail.com>
+Date: Wed, 18 May 2022 10:27:26 +0300
+Subject: ath10k: improve tx status reporting
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+We use ieee80211_tx_status() to report each completed tx frame.
+Internally, this function calls sta_info_get_by_addrs(), what has a
+couple of drawbacks:
+1. additional station lookup causes a performance degradation;
+2. mac80211 can not properly account Ethernet encapsulated frames due
+   to the inability to properly determine the destination (station) MAC
+   address since ieee80211_tx_status() assumes the frame has a 802.11
+   header.
+
+The latter is especially destructive if we want to use hardware frames
+encapsulation.
+
+To fix both of these issues, replace ieee80211_tx_status() with
+ieee80211_tx_status_ext() call and feed it station pointer from the tx
+queue associated with the transmitted frame.
+
+Tested-on: QCA9888 hw2.0 PCI 10.4-3.9.0.2-00131
+Tested-on: QCA6174 hw3.2 PCI WLAN.RM.4.4.1-00157-QCARMSWPZ-1
+
+Signed-off-by: Sergey Ryazanov <ryazanov.s.a@gmail.com>
+Tested-by: Oldřich Jedlička <oldium.pro@gmail.com> # TP-Link Archer C7 v4 & v5 (QCA9563 + QCA9880)
+Tested-by: Edward Matijevic <motolav@gmail.com> # TP-Link Archer C2600 (IPQ8064 + QCA9980 10.4.1.00030-1)
+Tested-by: Edward Matijevic <motolav@gmail.com> # QCA9377 PCI in Sta mode
+Tested-by: Zhijun You <hujy652@gmail.com> # NETGEAR R7800 (QCA9984 10.4-3.9.0.2-00159)
+Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
+Link: https://lore.kernel.org/r/20220516032519.29831-2-ryazanov.s.a@gmail.com
+---
+ drivers/net/wireless/ath/ath10k/txrx.c | 15 ++++++++++++++-
+ 1 file changed, 14 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/wireless/ath/ath10k/txrx.c
++++ b/drivers/net/wireless/ath/ath10k/txrx.c
+@@ -43,6 +43,7 @@ out:
+ int ath10k_txrx_tx_unref(struct ath10k_htt *htt,
+                        const struct htt_tx_done *tx_done)
+ {
++      struct ieee80211_tx_status status;
+       struct ath10k *ar = htt->ar;
+       struct device *dev = ar->dev;
+       struct ieee80211_tx_info *info;
+@@ -128,7 +129,19 @@ int ath10k_txrx_tx_unref(struct ath10k_h
+               info->status.is_valid_ack_signal = true;
+       }
+-      ieee80211_tx_status(htt->ar->hw, msdu);
++      memset(&status, 0, sizeof(status));
++      status.skb = msdu;
++      status.info = info;
++
++      rcu_read_lock();
++
++      if (txq)
++              status.sta = txq->sta;
++
++      ieee80211_tx_status_ext(htt->ar->hw, &status);
++
++      rcu_read_unlock();
++
+       /* we do not own the msdu anymore */
+       return 0;
diff --git a/package/kernel/mac80211/patches/ath10k/081-02-ath10k-turn-rawmode-into-frame-mode.patch b/package/kernel/mac80211/patches/ath10k/081-02-ath10k-turn-rawmode-into-frame-mode.patch
deleted file mode 100644 (file)
index e672815..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-From a09740548275a74b897654b3aca5af589289b57a Mon Sep 17 00:00:00 2001
-From: Sergey Ryazanov <ryazanov.s.a@gmail.com>
-Date: Mon, 16 May 2022 13:26:00 +0300
-Subject: ath10k: turn rawmode into frame_mode
-
-Turn boolean rawmode module param into integer frame_mode param that
-contains value from ath10k_hw_txrx_mode enum. As earlier the default
-param value is non-RAW (native Wi-Fi) encapsulation. The param name
-is selected to be consistent with the similar ath11k param.
-
-This is a preparation step for upcoming encapsulation offloading
-support.
-
-Signed-off-by: Sergey Ryazanov <ryazanov.s.a@gmail.com>
-Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
-Link: https://lore.kernel.org/r/20220516032519.29831-4-ryazanov.s.a@gmail.com
----
- drivers/net/wireless/ath/ath10k/core.c | 11 +++++++----
- drivers/net/wireless/ath/ath10k/core.h |  1 +
- 2 files changed, 8 insertions(+), 4 deletions(-)
-
---- a/drivers/net/wireless/ath/ath10k/core.c
-+++ b/drivers/net/wireless/ath/ath10k/core.c
-@@ -32,9 +32,11 @@ EXPORT_SYMBOL(ath10k_debug_mask);
- static unsigned int ath10k_cryptmode_param;
- static bool uart_print;
- static bool skip_otp;
--static bool rawmode;
- static bool fw_diag_log;
-+/* frame mode values are mapped as per enum ath10k_hw_txrx_mode */
-+unsigned int ath10k_frame_mode = ATH10K_HW_TXRX_NATIVE_WIFI;
-+
- unsigned long ath10k_coredump_mask = BIT(ATH10K_FW_CRASH_DUMP_REGISTERS) |
-                                    BIT(ATH10K_FW_CRASH_DUMP_CE_DATA);
-@@ -43,15 +45,16 @@ module_param_named(debug_mask, ath10k_de
- module_param_named(cryptmode, ath10k_cryptmode_param, uint, 0644);
- module_param(uart_print, bool, 0644);
- module_param(skip_otp, bool, 0644);
--module_param(rawmode, bool, 0644);
- module_param(fw_diag_log, bool, 0644);
-+module_param_named(frame_mode, ath10k_frame_mode, uint, 0644);
- module_param_named(coredump_mask, ath10k_coredump_mask, ulong, 0444);
- MODULE_PARM_DESC(debug_mask, "Debugging mask");
- MODULE_PARM_DESC(uart_print, "Uart target debugging");
- MODULE_PARM_DESC(skip_otp, "Skip otp failure for calibration in testmode");
- MODULE_PARM_DESC(cryptmode, "Crypto mode: 0-hardware, 1-software");
--MODULE_PARM_DESC(rawmode, "Use raw 802.11 frame datapath");
-+MODULE_PARM_DESC(frame_mode,
-+               "Datapath frame mode (0: raw, 1: native wifi (default))");
- MODULE_PARM_DESC(coredump_mask, "Bitfield of what to include in firmware crash file");
- MODULE_PARM_DESC(fw_diag_log, "Diag based fw log debugging");
-@@ -2487,7 +2490,7 @@ static int ath10k_core_init_firmware_fea
-       ar->htt.max_num_amsdu = ATH10K_HTT_MAX_NUM_AMSDU_DEFAULT;
-       ar->htt.max_num_ampdu = ATH10K_HTT_MAX_NUM_AMPDU_DEFAULT;
--      if (rawmode) {
-+      if (ath10k_frame_mode == ATH10K_HW_TXRX_RAW) {
-               if (!test_bit(ATH10K_FW_FEATURE_RAW_MODE_SUPPORT,
-                             fw_file->fw_features)) {
-                       ath10k_err(ar, "rawmode = 1 requires support from firmware");
---- a/drivers/net/wireless/ath/ath10k/core.h
-+++ b/drivers/net/wireless/ath/ath10k/core.h
-@@ -1311,6 +1311,7 @@ static inline bool ath10k_peer_stats_ena
-       return false;
- }
-+extern unsigned int ath10k_frame_mode;
- extern unsigned long ath10k_coredump_mask;
- void ath10k_core_napi_sync_disable(struct ath10k *ar);
diff --git a/package/kernel/mac80211/patches/ath10k/081-02-v6.0-ath10k-turn-rawmode-into-frame-mode.patch b/package/kernel/mac80211/patches/ath10k/081-02-v6.0-ath10k-turn-rawmode-into-frame-mode.patch
new file mode 100644 (file)
index 0000000..e672815
--- /dev/null
@@ -0,0 +1,74 @@
+From a09740548275a74b897654b3aca5af589289b57a Mon Sep 17 00:00:00 2001
+From: Sergey Ryazanov <ryazanov.s.a@gmail.com>
+Date: Mon, 16 May 2022 13:26:00 +0300
+Subject: ath10k: turn rawmode into frame_mode
+
+Turn boolean rawmode module param into integer frame_mode param that
+contains value from ath10k_hw_txrx_mode enum. As earlier the default
+param value is non-RAW (native Wi-Fi) encapsulation. The param name
+is selected to be consistent with the similar ath11k param.
+
+This is a preparation step for upcoming encapsulation offloading
+support.
+
+Signed-off-by: Sergey Ryazanov <ryazanov.s.a@gmail.com>
+Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
+Link: https://lore.kernel.org/r/20220516032519.29831-4-ryazanov.s.a@gmail.com
+---
+ drivers/net/wireless/ath/ath10k/core.c | 11 +++++++----
+ drivers/net/wireless/ath/ath10k/core.h |  1 +
+ 2 files changed, 8 insertions(+), 4 deletions(-)
+
+--- a/drivers/net/wireless/ath/ath10k/core.c
++++ b/drivers/net/wireless/ath/ath10k/core.c
+@@ -32,9 +32,11 @@ EXPORT_SYMBOL(ath10k_debug_mask);
+ static unsigned int ath10k_cryptmode_param;
+ static bool uart_print;
+ static bool skip_otp;
+-static bool rawmode;
+ static bool fw_diag_log;
++/* frame mode values are mapped as per enum ath10k_hw_txrx_mode */
++unsigned int ath10k_frame_mode = ATH10K_HW_TXRX_NATIVE_WIFI;
++
+ unsigned long ath10k_coredump_mask = BIT(ATH10K_FW_CRASH_DUMP_REGISTERS) |
+                                    BIT(ATH10K_FW_CRASH_DUMP_CE_DATA);
+@@ -43,15 +45,16 @@ module_param_named(debug_mask, ath10k_de
+ module_param_named(cryptmode, ath10k_cryptmode_param, uint, 0644);
+ module_param(uart_print, bool, 0644);
+ module_param(skip_otp, bool, 0644);
+-module_param(rawmode, bool, 0644);
+ module_param(fw_diag_log, bool, 0644);
++module_param_named(frame_mode, ath10k_frame_mode, uint, 0644);
+ module_param_named(coredump_mask, ath10k_coredump_mask, ulong, 0444);
+ MODULE_PARM_DESC(debug_mask, "Debugging mask");
+ MODULE_PARM_DESC(uart_print, "Uart target debugging");
+ MODULE_PARM_DESC(skip_otp, "Skip otp failure for calibration in testmode");
+ MODULE_PARM_DESC(cryptmode, "Crypto mode: 0-hardware, 1-software");
+-MODULE_PARM_DESC(rawmode, "Use raw 802.11 frame datapath");
++MODULE_PARM_DESC(frame_mode,
++               "Datapath frame mode (0: raw, 1: native wifi (default))");
+ MODULE_PARM_DESC(coredump_mask, "Bitfield of what to include in firmware crash file");
+ MODULE_PARM_DESC(fw_diag_log, "Diag based fw log debugging");
+@@ -2487,7 +2490,7 @@ static int ath10k_core_init_firmware_fea
+       ar->htt.max_num_amsdu = ATH10K_HTT_MAX_NUM_AMSDU_DEFAULT;
+       ar->htt.max_num_ampdu = ATH10K_HTT_MAX_NUM_AMPDU_DEFAULT;
+-      if (rawmode) {
++      if (ath10k_frame_mode == ATH10K_HW_TXRX_RAW) {
+               if (!test_bit(ATH10K_FW_FEATURE_RAW_MODE_SUPPORT,
+                             fw_file->fw_features)) {
+                       ath10k_err(ar, "rawmode = 1 requires support from firmware");
+--- a/drivers/net/wireless/ath/ath10k/core.h
++++ b/drivers/net/wireless/ath/ath10k/core.h
+@@ -1311,6 +1311,7 @@ static inline bool ath10k_peer_stats_ena
+       return false;
+ }
++extern unsigned int ath10k_frame_mode;
+ extern unsigned long ath10k_coredump_mask;
+ void ath10k_core_napi_sync_disable(struct ath10k *ar);
diff --git a/package/kernel/mac80211/patches/ath10k/081-03-ath10k-htt-tx-do-not-interpret-Eth-frames-as-WiFi.patch b/package/kernel/mac80211/patches/ath10k/081-03-ath10k-htt-tx-do-not-interpret-Eth-frames-as-WiFi.patch
deleted file mode 100644 (file)
index a669c77..0000000
+++ /dev/null
@@ -1,163 +0,0 @@
-From 70f119fb82af7f7417dc659faf02c91e1f853739 Mon Sep 17 00:00:00 2001
-From: Sergey Ryazanov <ryazanov.s.a@gmail.com>
-Date: Mon, 16 May 2022 13:26:00 +0300
-Subject: ath10k: htt_tx: do not interpret Eth frames as WiFi
-
-The xmit path for the Ethernet encapsulated frames become more or less
-usable since d740d8fd2439 ("ath10k: unify tx mode and dispatch"). This
-change reorganize the xmit path in a manageable way to properly support
-various tx modes, but misses that the Ethernet encapsulated frame is a
-special case. We do not have an IEEE 802.11 header at the begining of
-them. But the HTT Tx handler still interprets first bytes of each frame
-as an IEEE 802.11 Frame Control field.
-
-Than this code was copied by e62ee5c381c5 ("ath10k: Add support for
-htt_data_tx_desc_64 descriptor") and a2097d6444c3 ("ath10k: htt: High
-latency TX support") to another handlers. In fact the issue in the high
-latency (HL) handler was introduced by 83ac260151e7 ("ath10k: add mic
-bytes for pmf management packet").
-
-Ethernet encapsulated frame tx mode stay unused until 75d85fd9993c
-("ath10k: introduce basic tdls functionality") started using it for TDLS
-frames to avoid key selection issue in some firmwares.
-
-Trying to interpret the begining of an Ethernet encapsulated frame as an
-IEEE 802.11 header was not hurt us noticeably since we need to meet two
-conditions: (1) xmit should be performed towards a TDLS peer, and (2)
-the TDLS peer should have a specific OUI part of its MAC address. Looks
-like that the rareness in TDLS communications of OUIs that can be
-interpreted as an 802.11 management frame saves users from facing this
-issue earlier.
-
-Improve Ethernet tx mode support in the HTT Tx handler by avoiding
-interpreting its first bytes as an IEEE 802.11 header. While at it, make
-the ieee80211_hdr variable local to the code block that is guarded by
-!is_eth check. In this way, we clarify in which cases a frame can be
-interpreted as IEEE 802.11, and saves us from similar issues in the
-future.
-
-Credits: this change as part of xmit encapsulation offloading support
-was originally made by QCA and then submitted for inclusion by John
-Crispin [1]. But the whole work was not accepted due to the lack of a
-part for 64-bits descriptors [2]. Zhijun You then pointed this out to me
-in a reply to my initial RFC patch series. And I made this slightly
-reworked version that covered all the HTT Tx handler variants.
-
-1. https://lore.kernel.org/all/20191216092207.31032-1-john@phrozen.org/
-2. https://patchwork.kernel.org/project/linux-wireless/patch/20191216092207.31032-1-john@phrozen.org/
-
-Reported-by: Zhijun You <hujy652@gmail.com>
-Signed-off-by: Vasanthakumar Thiagarajan <vthiagar@qti.qualcomm.com>
-Signed-off-by: John Crispin <john@phrozen.org>
-Signed-off-by: Sergey Ryazanov <ryazanov.s.a@gmail.com>
-Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
-Link: https://lore.kernel.org/r/20220516032519.29831-3-ryazanov.s.a@gmail.com
----
- drivers/net/wireless/ath/ath10k/htt_tx.c | 61 ++++++++++++++++++--------------
- 1 file changed, 35 insertions(+), 26 deletions(-)
-
---- a/drivers/net/wireless/ath/ath10k/htt_tx.c
-+++ b/drivers/net/wireless/ath/ath10k/htt_tx.c
-@@ -1295,7 +1295,6 @@ static int ath10k_htt_tx_hl(struct ath10
-       struct ath10k *ar = htt->ar;
-       int res, data_len;
-       struct htt_cmd_hdr *cmd_hdr;
--      struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)msdu->data;
-       struct htt_data_tx_desc *tx_desc;
-       struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(msdu);
-       struct sk_buff *tmp_skb;
-@@ -1306,11 +1305,15 @@ static int ath10k_htt_tx_hl(struct ath10
-       u16 flags1 = 0;
-       u16 msdu_id = 0;
--      if ((ieee80211_is_action(hdr->frame_control) ||
--           ieee80211_is_deauth(hdr->frame_control) ||
--           ieee80211_is_disassoc(hdr->frame_control)) &&
--           ieee80211_has_protected(hdr->frame_control)) {
--              skb_put(msdu, IEEE80211_CCMP_MIC_LEN);
-+      if (!is_eth) {
-+              struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)msdu->data;
-+
-+              if ((ieee80211_is_action(hdr->frame_control) ||
-+                   ieee80211_is_deauth(hdr->frame_control) ||
-+                   ieee80211_is_disassoc(hdr->frame_control)) &&
-+                   ieee80211_has_protected(hdr->frame_control)) {
-+                      skb_put(msdu, IEEE80211_CCMP_MIC_LEN);
-+              }
-       }
-       data_len = msdu->len;
-@@ -1407,7 +1410,6 @@ static int ath10k_htt_tx_32(struct ath10
- {
-       struct ath10k *ar = htt->ar;
-       struct device *dev = ar->dev;
--      struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)msdu->data;
-       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(msdu);
-       struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(msdu);
-       struct ath10k_hif_sg_item sg_items[2];
-@@ -1439,15 +1441,19 @@ static int ath10k_htt_tx_32(struct ath10
-       txbuf_paddr = htt->txbuf.paddr +
-                     (sizeof(struct ath10k_htt_txbuf_32) * msdu_id);
--      if ((ieee80211_is_action(hdr->frame_control) ||
--           ieee80211_is_deauth(hdr->frame_control) ||
--           ieee80211_is_disassoc(hdr->frame_control)) &&
--           ieee80211_has_protected(hdr->frame_control)) {
--              skb_put(msdu, IEEE80211_CCMP_MIC_LEN);
--      } else if (!(skb_cb->flags & ATH10K_SKB_F_NO_HWCRYPT) &&
--                 txmode == ATH10K_HW_TXRX_RAW &&
--                 ieee80211_has_protected(hdr->frame_control)) {
--              skb_put(msdu, IEEE80211_CCMP_MIC_LEN);
-+      if (!is_eth) {
-+              struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)msdu->data;
-+
-+              if ((ieee80211_is_action(hdr->frame_control) ||
-+                   ieee80211_is_deauth(hdr->frame_control) ||
-+                   ieee80211_is_disassoc(hdr->frame_control)) &&
-+                   ieee80211_has_protected(hdr->frame_control)) {
-+                      skb_put(msdu, IEEE80211_CCMP_MIC_LEN);
-+              } else if (!(skb_cb->flags & ATH10K_SKB_F_NO_HWCRYPT) &&
-+                         txmode == ATH10K_HW_TXRX_RAW &&
-+                         ieee80211_has_protected(hdr->frame_control)) {
-+                      skb_put(msdu, IEEE80211_CCMP_MIC_LEN);
-+              }
-       }
-       skb_cb->paddr = dma_map_single(dev, msdu->data, msdu->len,
-@@ -1609,7 +1615,6 @@ static int ath10k_htt_tx_64(struct ath10
- {
-       struct ath10k *ar = htt->ar;
-       struct device *dev = ar->dev;
--      struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)msdu->data;
-       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(msdu);
-       struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(msdu);
-       struct ath10k_hif_sg_item sg_items[2];
-@@ -1641,15 +1646,19 @@ static int ath10k_htt_tx_64(struct ath10
-       txbuf_paddr = htt->txbuf.paddr +
-                     (sizeof(struct ath10k_htt_txbuf_64) * msdu_id);
--      if ((ieee80211_is_action(hdr->frame_control) ||
--           ieee80211_is_deauth(hdr->frame_control) ||
--           ieee80211_is_disassoc(hdr->frame_control)) &&
--           ieee80211_has_protected(hdr->frame_control)) {
--              skb_put(msdu, IEEE80211_CCMP_MIC_LEN);
--      } else if (!(skb_cb->flags & ATH10K_SKB_F_NO_HWCRYPT) &&
--                 txmode == ATH10K_HW_TXRX_RAW &&
--                 ieee80211_has_protected(hdr->frame_control)) {
--              skb_put(msdu, IEEE80211_CCMP_MIC_LEN);
-+      if (!is_eth) {
-+              struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)msdu->data;
-+
-+              if ((ieee80211_is_action(hdr->frame_control) ||
-+                   ieee80211_is_deauth(hdr->frame_control) ||
-+                   ieee80211_is_disassoc(hdr->frame_control)) &&
-+                   ieee80211_has_protected(hdr->frame_control)) {
-+                      skb_put(msdu, IEEE80211_CCMP_MIC_LEN);
-+              } else if (!(skb_cb->flags & ATH10K_SKB_F_NO_HWCRYPT) &&
-+                         txmode == ATH10K_HW_TXRX_RAW &&
-+                         ieee80211_has_protected(hdr->frame_control)) {
-+                      skb_put(msdu, IEEE80211_CCMP_MIC_LEN);
-+              }
-       }
-       skb_cb->paddr = dma_map_single(dev, msdu->data, msdu->len,
diff --git a/package/kernel/mac80211/patches/ath10k/081-03-v6.0-ath10k-htt-tx-do-not-interpret-Eth-frames-as-WiFi.patch b/package/kernel/mac80211/patches/ath10k/081-03-v6.0-ath10k-htt-tx-do-not-interpret-Eth-frames-as-WiFi.patch
new file mode 100644 (file)
index 0000000..a669c77
--- /dev/null
@@ -0,0 +1,163 @@
+From 70f119fb82af7f7417dc659faf02c91e1f853739 Mon Sep 17 00:00:00 2001
+From: Sergey Ryazanov <ryazanov.s.a@gmail.com>
+Date: Mon, 16 May 2022 13:26:00 +0300
+Subject: ath10k: htt_tx: do not interpret Eth frames as WiFi
+
+The xmit path for the Ethernet encapsulated frames become more or less
+usable since d740d8fd2439 ("ath10k: unify tx mode and dispatch"). This
+change reorganize the xmit path in a manageable way to properly support
+various tx modes, but misses that the Ethernet encapsulated frame is a
+special case. We do not have an IEEE 802.11 header at the begining of
+them. But the HTT Tx handler still interprets first bytes of each frame
+as an IEEE 802.11 Frame Control field.
+
+Than this code was copied by e62ee5c381c5 ("ath10k: Add support for
+htt_data_tx_desc_64 descriptor") and a2097d6444c3 ("ath10k: htt: High
+latency TX support") to another handlers. In fact the issue in the high
+latency (HL) handler was introduced by 83ac260151e7 ("ath10k: add mic
+bytes for pmf management packet").
+
+Ethernet encapsulated frame tx mode stay unused until 75d85fd9993c
+("ath10k: introduce basic tdls functionality") started using it for TDLS
+frames to avoid key selection issue in some firmwares.
+
+Trying to interpret the begining of an Ethernet encapsulated frame as an
+IEEE 802.11 header was not hurt us noticeably since we need to meet two
+conditions: (1) xmit should be performed towards a TDLS peer, and (2)
+the TDLS peer should have a specific OUI part of its MAC address. Looks
+like that the rareness in TDLS communications of OUIs that can be
+interpreted as an 802.11 management frame saves users from facing this
+issue earlier.
+
+Improve Ethernet tx mode support in the HTT Tx handler by avoiding
+interpreting its first bytes as an IEEE 802.11 header. While at it, make
+the ieee80211_hdr variable local to the code block that is guarded by
+!is_eth check. In this way, we clarify in which cases a frame can be
+interpreted as IEEE 802.11, and saves us from similar issues in the
+future.
+
+Credits: this change as part of xmit encapsulation offloading support
+was originally made by QCA and then submitted for inclusion by John
+Crispin [1]. But the whole work was not accepted due to the lack of a
+part for 64-bits descriptors [2]. Zhijun You then pointed this out to me
+in a reply to my initial RFC patch series. And I made this slightly
+reworked version that covered all the HTT Tx handler variants.
+
+1. https://lore.kernel.org/all/20191216092207.31032-1-john@phrozen.org/
+2. https://patchwork.kernel.org/project/linux-wireless/patch/20191216092207.31032-1-john@phrozen.org/
+
+Reported-by: Zhijun You <hujy652@gmail.com>
+Signed-off-by: Vasanthakumar Thiagarajan <vthiagar@qti.qualcomm.com>
+Signed-off-by: John Crispin <john@phrozen.org>
+Signed-off-by: Sergey Ryazanov <ryazanov.s.a@gmail.com>
+Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
+Link: https://lore.kernel.org/r/20220516032519.29831-3-ryazanov.s.a@gmail.com
+---
+ drivers/net/wireless/ath/ath10k/htt_tx.c | 61 ++++++++++++++++++--------------
+ 1 file changed, 35 insertions(+), 26 deletions(-)
+
+--- a/drivers/net/wireless/ath/ath10k/htt_tx.c
++++ b/drivers/net/wireless/ath/ath10k/htt_tx.c
+@@ -1295,7 +1295,6 @@ static int ath10k_htt_tx_hl(struct ath10
+       struct ath10k *ar = htt->ar;
+       int res, data_len;
+       struct htt_cmd_hdr *cmd_hdr;
+-      struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)msdu->data;
+       struct htt_data_tx_desc *tx_desc;
+       struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(msdu);
+       struct sk_buff *tmp_skb;
+@@ -1306,11 +1305,15 @@ static int ath10k_htt_tx_hl(struct ath10
+       u16 flags1 = 0;
+       u16 msdu_id = 0;
+-      if ((ieee80211_is_action(hdr->frame_control) ||
+-           ieee80211_is_deauth(hdr->frame_control) ||
+-           ieee80211_is_disassoc(hdr->frame_control)) &&
+-           ieee80211_has_protected(hdr->frame_control)) {
+-              skb_put(msdu, IEEE80211_CCMP_MIC_LEN);
++      if (!is_eth) {
++              struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)msdu->data;
++
++              if ((ieee80211_is_action(hdr->frame_control) ||
++                   ieee80211_is_deauth(hdr->frame_control) ||
++                   ieee80211_is_disassoc(hdr->frame_control)) &&
++                   ieee80211_has_protected(hdr->frame_control)) {
++                      skb_put(msdu, IEEE80211_CCMP_MIC_LEN);
++              }
+       }
+       data_len = msdu->len;
+@@ -1407,7 +1410,6 @@ static int ath10k_htt_tx_32(struct ath10
+ {
+       struct ath10k *ar = htt->ar;
+       struct device *dev = ar->dev;
+-      struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)msdu->data;
+       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(msdu);
+       struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(msdu);
+       struct ath10k_hif_sg_item sg_items[2];
+@@ -1439,15 +1441,19 @@ static int ath10k_htt_tx_32(struct ath10
+       txbuf_paddr = htt->txbuf.paddr +
+                     (sizeof(struct ath10k_htt_txbuf_32) * msdu_id);
+-      if ((ieee80211_is_action(hdr->frame_control) ||
+-           ieee80211_is_deauth(hdr->frame_control) ||
+-           ieee80211_is_disassoc(hdr->frame_control)) &&
+-           ieee80211_has_protected(hdr->frame_control)) {
+-              skb_put(msdu, IEEE80211_CCMP_MIC_LEN);
+-      } else if (!(skb_cb->flags & ATH10K_SKB_F_NO_HWCRYPT) &&
+-                 txmode == ATH10K_HW_TXRX_RAW &&
+-                 ieee80211_has_protected(hdr->frame_control)) {
+-              skb_put(msdu, IEEE80211_CCMP_MIC_LEN);
++      if (!is_eth) {
++              struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)msdu->data;
++
++              if ((ieee80211_is_action(hdr->frame_control) ||
++                   ieee80211_is_deauth(hdr->frame_control) ||
++                   ieee80211_is_disassoc(hdr->frame_control)) &&
++                   ieee80211_has_protected(hdr->frame_control)) {
++                      skb_put(msdu, IEEE80211_CCMP_MIC_LEN);
++              } else if (!(skb_cb->flags & ATH10K_SKB_F_NO_HWCRYPT) &&
++                         txmode == ATH10K_HW_TXRX_RAW &&
++                         ieee80211_has_protected(hdr->frame_control)) {
++                      skb_put(msdu, IEEE80211_CCMP_MIC_LEN);
++              }
+       }
+       skb_cb->paddr = dma_map_single(dev, msdu->data, msdu->len,
+@@ -1609,7 +1615,6 @@ static int ath10k_htt_tx_64(struct ath10
+ {
+       struct ath10k *ar = htt->ar;
+       struct device *dev = ar->dev;
+-      struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)msdu->data;
+       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(msdu);
+       struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(msdu);
+       struct ath10k_hif_sg_item sg_items[2];
+@@ -1641,15 +1646,19 @@ static int ath10k_htt_tx_64(struct ath10
+       txbuf_paddr = htt->txbuf.paddr +
+                     (sizeof(struct ath10k_htt_txbuf_64) * msdu_id);
+-      if ((ieee80211_is_action(hdr->frame_control) ||
+-           ieee80211_is_deauth(hdr->frame_control) ||
+-           ieee80211_is_disassoc(hdr->frame_control)) &&
+-           ieee80211_has_protected(hdr->frame_control)) {
+-              skb_put(msdu, IEEE80211_CCMP_MIC_LEN);
+-      } else if (!(skb_cb->flags & ATH10K_SKB_F_NO_HWCRYPT) &&
+-                 txmode == ATH10K_HW_TXRX_RAW &&
+-                 ieee80211_has_protected(hdr->frame_control)) {
+-              skb_put(msdu, IEEE80211_CCMP_MIC_LEN);
++      if (!is_eth) {
++              struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)msdu->data;
++
++              if ((ieee80211_is_action(hdr->frame_control) ||
++                   ieee80211_is_deauth(hdr->frame_control) ||
++                   ieee80211_is_disassoc(hdr->frame_control)) &&
++                   ieee80211_has_protected(hdr->frame_control)) {
++                      skb_put(msdu, IEEE80211_CCMP_MIC_LEN);
++              } else if (!(skb_cb->flags & ATH10K_SKB_F_NO_HWCRYPT) &&
++                         txmode == ATH10K_HW_TXRX_RAW &&
++                         ieee80211_has_protected(hdr->frame_control)) {
++                      skb_put(msdu, IEEE80211_CCMP_MIC_LEN);
++              }
+       }
+       skb_cb->paddr = dma_map_single(dev, msdu->data, msdu->len,
diff --git a/package/kernel/mac80211/patches/ath10k/081-04-ath10k-add-encapsulation-offloading-support.patch b/package/kernel/mac80211/patches/ath10k/081-04-ath10k-add-encapsulation-offloading-support.patch
deleted file mode 100644 (file)
index abca7aa..0000000
+++ /dev/null
@@ -1,194 +0,0 @@
-From af6d8265c47e46881b80c6b073f53c8c4af52d28 Mon Sep 17 00:00:00 2001
-From: Sergey Ryazanov <ryazanov.s.a@gmail.com>
-Date: Mon, 16 May 2022 13:26:00 +0300
-Subject: ath10k: add encapsulation offloading support
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Frame encapsulation from Ethernet into the IEEE 802.11 frame format
-takes a considerable host CPU time on the xmit path. The firmware is
-able to do this operation for us, so enable encapsulation offloading for
-AP and Sta interface types to improve overall system performance.
-
-The driver is almost ready for encapsulation offloading support. There
-are only a few places where the driver assumes the frame format is IEEE
-802.11 that need to be fixed.
-
-Encapsulation offloading is currently disabled by default and the driver
-utilizes mac80211 encapsulation support. To activate offloading, the
-frame_mode=2 parameter should be passed during module loading.
-
-On a QCA9563+QCA9888-based access point in bridged mode, encapsulation
-offloading increases TCP 16-streams DL throughput from 365 to 396 mbps
-(+8%) and UDP DL throughput from 436 to 483 mbps (+11%).
-
-Tested-on: QCA9888 hw2.0 PCI 10.4-3.9.0.2-00131
-Tested-on: QCA6174 hw3.2 PCI WLAN.RM.4.4.1-00157-QCARMSWPZ-1
-Signed-off-by: Sergey Ryazanov <ryazanov.s.a@gmail.com>
-Tested-by: Oldřich Jedlička <oldium.pro@gmail.com> # TP-Link Archer C7 v4 & v5 (QCA9563 + QCA9880)
-Tested-by: Edward Matijevic <motolav@gmail.com> # TP-Link Archer C2600 (IPQ8064 + QCA9980 10.4.1.00030-1)
-Tested-by: Edward Matijevic <motolav@gmail.com> # QCA9377 PCI in Sta mode
-Tested-by: Zhijun You <hujy652@gmail.com> # NETGEAR R7800 (QCA9984 10.4-3.9.0.2-00159)
-Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
-Link: https://lore.kernel.org/r/20220516032519.29831-5-ryazanov.s.a@gmail.com
----
- drivers/net/wireless/ath/ath10k/core.c |  2 +-
- drivers/net/wireless/ath/ath10k/mac.c  | 67 +++++++++++++++++++++++++++-------
- 2 files changed, 55 insertions(+), 14 deletions(-)
-
---- a/drivers/net/wireless/ath/ath10k/core.c
-+++ b/drivers/net/wireless/ath/ath10k/core.c
-@@ -54,7 +54,7 @@ MODULE_PARM_DESC(uart_print, "Uart targe
- MODULE_PARM_DESC(skip_otp, "Skip otp failure for calibration in testmode");
- MODULE_PARM_DESC(cryptmode, "Crypto mode: 0-hardware, 1-software");
- MODULE_PARM_DESC(frame_mode,
--               "Datapath frame mode (0: raw, 1: native wifi (default))");
-+               "Datapath frame mode (0: raw, 1: native wifi (default), 2: ethernet)");
- MODULE_PARM_DESC(coredump_mask, "Bitfield of what to include in firmware crash file");
- MODULE_PARM_DESC(fw_diag_log, "Diag based fw log debugging");
---- a/drivers/net/wireless/ath/ath10k/mac.c
-+++ b/drivers/net/wireless/ath/ath10k/mac.c
-@@ -3710,6 +3710,9 @@ ath10k_mac_tx_h_get_txmode(struct ath10k
-       const struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(skb);
-       __le16 fc = hdr->frame_control;
-+      if (IEEE80211_SKB_CB(skb)->flags & IEEE80211_TX_CTL_HW_80211_ENCAP)
-+              return ATH10K_HW_TXRX_ETHERNET;
-+
-       if (!vif || vif->type == NL80211_IFTYPE_MONITOR)
-               return ATH10K_HW_TXRX_RAW;
-@@ -3870,6 +3873,12 @@ static void ath10k_mac_tx_h_fill_cb(stru
-       bool noack = false;
-       cb->flags = 0;
-+
-+      if (info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP) {
-+              cb->flags |= ATH10K_SKB_F_QOS;  /* Assume data frames are QoS */
-+              goto finish_cb_fill;
-+      }
-+
-       if (!ath10k_tx_h_use_hwcrypto(vif, skb))
-               cb->flags |= ATH10K_SKB_F_NO_HWCRYPT;
-@@ -3908,6 +3917,7 @@ static void ath10k_mac_tx_h_fill_cb(stru
-               cb->flags |= ATH10K_SKB_F_RAW_TX;
-       }
-+finish_cb_fill:
-       cb->vif = vif;
-       cb->txq = txq;
-       cb->airtime_est = airtime;
-@@ -4031,7 +4041,11 @@ static int ath10k_mac_tx(struct ath10k *
-               ath10k_tx_h_seq_no(vif, skb);
-               break;
-       case ATH10K_HW_TXRX_ETHERNET:
--              ath10k_tx_h_8023(skb);
-+              /* Convert 802.11->802.3 header only if the frame was erlier
-+               * encapsulated to 802.11 by mac80211. Otherwise pass it as is.
-+               */
-+              if (!(info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP))
-+                      ath10k_tx_h_8023(skb);
-               break;
-       case ATH10K_HW_TXRX_RAW:
-               if (!test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags) &&
-@@ -4643,12 +4657,10 @@ static void ath10k_mac_op_tx(struct ieee
-       struct ieee80211_vif *vif = info->control.vif;
-       struct ieee80211_sta *sta = control->sta;
-       struct ieee80211_txq *txq = NULL;
--      struct ieee80211_hdr *hdr = (void *)skb->data;
-       enum ath10k_hw_txrx_mode txmode;
-       enum ath10k_mac_tx_path txpath;
-       bool is_htt;
-       bool is_mgmt;
--      bool is_presp;
-       int ret;
-       u16 airtime;
-@@ -4662,8 +4674,14 @@ static void ath10k_mac_op_tx(struct ieee
-       is_mgmt = (txpath == ATH10K_MAC_TX_HTT_MGMT);
-       if (is_htt) {
-+              bool is_presp = false;
-+
-               spin_lock_bh(&ar->htt.tx_lock);
--              is_presp = ieee80211_is_probe_resp(hdr->frame_control);
-+              if (!(info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP)) {
-+                      struct ieee80211_hdr *hdr = (void *)skb->data;
-+
-+                      is_presp = ieee80211_is_probe_resp(hdr->frame_control);
-+              }
-               ret = ath10k_htt_tx_inc_pending(htt);
-               if (ret) {
-@@ -5463,6 +5481,30 @@ static int ath10k_mac_set_txbf_conf(stru
-                                        ar->wmi.vdev_param->txbf, value);
- }
-+static void ath10k_update_vif_offload(struct ieee80211_hw *hw,
-+                                    struct ieee80211_vif *vif)
-+{
-+      struct ath10k_vif *arvif = (void *)vif->drv_priv;
-+      struct ath10k *ar = hw->priv;
-+      u32 vdev_param;
-+      int ret;
-+
-+      if (ath10k_frame_mode != ATH10K_HW_TXRX_ETHERNET ||
-+          ar->wmi.vdev_param->tx_encap_type == WMI_VDEV_PARAM_UNSUPPORTED ||
-+           (vif->type != NL80211_IFTYPE_STATION &&
-+            vif->type != NL80211_IFTYPE_AP))
-+              vif->offload_flags &= ~IEEE80211_OFFLOAD_ENCAP_ENABLED;
-+
-+      vdev_param = ar->wmi.vdev_param->tx_encap_type;
-+      ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
-+                                      ATH10K_HW_TXRX_NATIVE_WIFI);
-+      /* 10.X firmware does not support this VDEV parameter. Do not warn */
-+      if (ret && ret != -EOPNOTSUPP) {
-+              ath10k_warn(ar, "failed to set vdev %i TX encapsulation: %d\n",
-+                          arvif->vdev_id, ret);
-+      }
-+}
-+
- /*
-  * TODO:
-  * Figure out how to handle WMI_VDEV_SUBTYPE_P2P_DEVICE,
-@@ -5672,15 +5714,7 @@ static int ath10k_add_interface(struct i
-       arvif->def_wep_key_idx = -1;
--      vdev_param = ar->wmi.vdev_param->tx_encap_type;
--      ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
--                                      ATH10K_HW_TXRX_NATIVE_WIFI);
--      /* 10.X firmware does not support this VDEV parameter. Do not warn */
--      if (ret && ret != -EOPNOTSUPP) {
--              ath10k_warn(ar, "failed to set vdev %i TX encapsulation: %d\n",
--                          arvif->vdev_id, ret);
--              goto err_vdev_delete;
--      }
-+      ath10k_update_vif_offload(hw, vif);
-       /* Configuring number of spatial stream for monitor interface is causing
-        * target assert in qca9888 and qca6174.
-@@ -9368,6 +9402,7 @@ static const struct ieee80211_ops ath10k
-       .stop                           = ath10k_stop,
-       .config                         = ath10k_config,
-       .add_interface                  = ath10k_add_interface,
-+      .update_vif_offload             = ath10k_update_vif_offload,
-       .remove_interface               = ath10k_remove_interface,
-       .configure_filter               = ath10k_configure_filter,
-       .bss_info_changed               = ath10k_bss_info_changed,
-@@ -10037,6 +10072,12 @@ int ath10k_mac_register(struct ath10k *a
-       if (test_bit(WMI_SERVICE_TDLS_UAPSD_BUFFER_STA, ar->wmi.svc_map))
-               ieee80211_hw_set(ar->hw, SUPPORTS_TDLS_BUFFER_STA);
-+      if (ath10k_frame_mode == ATH10K_HW_TXRX_ETHERNET) {
-+              if (ar->wmi.vdev_param->tx_encap_type !=
-+                  WMI_VDEV_PARAM_UNSUPPORTED)
-+                      ieee80211_hw_set(ar->hw, SUPPORTS_TX_ENCAP_OFFLOAD);
-+      }
-+
-       ar->hw->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
-       ar->hw->wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;
-       ar->hw->wiphy->max_remain_on_channel_duration = 5000;
diff --git a/package/kernel/mac80211/patches/ath10k/081-04-v6.0-ath10k-add-encapsulation-offloading-support.patch b/package/kernel/mac80211/patches/ath10k/081-04-v6.0-ath10k-add-encapsulation-offloading-support.patch
new file mode 100644 (file)
index 0000000..abca7aa
--- /dev/null
@@ -0,0 +1,194 @@
+From af6d8265c47e46881b80c6b073f53c8c4af52d28 Mon Sep 17 00:00:00 2001
+From: Sergey Ryazanov <ryazanov.s.a@gmail.com>
+Date: Mon, 16 May 2022 13:26:00 +0300
+Subject: ath10k: add encapsulation offloading support
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Frame encapsulation from Ethernet into the IEEE 802.11 frame format
+takes a considerable host CPU time on the xmit path. The firmware is
+able to do this operation for us, so enable encapsulation offloading for
+AP and Sta interface types to improve overall system performance.
+
+The driver is almost ready for encapsulation offloading support. There
+are only a few places where the driver assumes the frame format is IEEE
+802.11 that need to be fixed.
+
+Encapsulation offloading is currently disabled by default and the driver
+utilizes mac80211 encapsulation support. To activate offloading, the
+frame_mode=2 parameter should be passed during module loading.
+
+On a QCA9563+QCA9888-based access point in bridged mode, encapsulation
+offloading increases TCP 16-streams DL throughput from 365 to 396 mbps
+(+8%) and UDP DL throughput from 436 to 483 mbps (+11%).
+
+Tested-on: QCA9888 hw2.0 PCI 10.4-3.9.0.2-00131
+Tested-on: QCA6174 hw3.2 PCI WLAN.RM.4.4.1-00157-QCARMSWPZ-1
+Signed-off-by: Sergey Ryazanov <ryazanov.s.a@gmail.com>
+Tested-by: Oldřich Jedlička <oldium.pro@gmail.com> # TP-Link Archer C7 v4 & v5 (QCA9563 + QCA9880)
+Tested-by: Edward Matijevic <motolav@gmail.com> # TP-Link Archer C2600 (IPQ8064 + QCA9980 10.4.1.00030-1)
+Tested-by: Edward Matijevic <motolav@gmail.com> # QCA9377 PCI in Sta mode
+Tested-by: Zhijun You <hujy652@gmail.com> # NETGEAR R7800 (QCA9984 10.4-3.9.0.2-00159)
+Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
+Link: https://lore.kernel.org/r/20220516032519.29831-5-ryazanov.s.a@gmail.com
+---
+ drivers/net/wireless/ath/ath10k/core.c |  2 +-
+ drivers/net/wireless/ath/ath10k/mac.c  | 67 +++++++++++++++++++++++++++-------
+ 2 files changed, 55 insertions(+), 14 deletions(-)
+
+--- a/drivers/net/wireless/ath/ath10k/core.c
++++ b/drivers/net/wireless/ath/ath10k/core.c
+@@ -54,7 +54,7 @@ MODULE_PARM_DESC(uart_print, "Uart targe
+ MODULE_PARM_DESC(skip_otp, "Skip otp failure for calibration in testmode");
+ MODULE_PARM_DESC(cryptmode, "Crypto mode: 0-hardware, 1-software");
+ MODULE_PARM_DESC(frame_mode,
+-               "Datapath frame mode (0: raw, 1: native wifi (default))");
++               "Datapath frame mode (0: raw, 1: native wifi (default), 2: ethernet)");
+ MODULE_PARM_DESC(coredump_mask, "Bitfield of what to include in firmware crash file");
+ MODULE_PARM_DESC(fw_diag_log, "Diag based fw log debugging");
+--- a/drivers/net/wireless/ath/ath10k/mac.c
++++ b/drivers/net/wireless/ath/ath10k/mac.c
+@@ -3710,6 +3710,9 @@ ath10k_mac_tx_h_get_txmode(struct ath10k
+       const struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(skb);
+       __le16 fc = hdr->frame_control;
++      if (IEEE80211_SKB_CB(skb)->flags & IEEE80211_TX_CTL_HW_80211_ENCAP)
++              return ATH10K_HW_TXRX_ETHERNET;
++
+       if (!vif || vif->type == NL80211_IFTYPE_MONITOR)
+               return ATH10K_HW_TXRX_RAW;
+@@ -3870,6 +3873,12 @@ static void ath10k_mac_tx_h_fill_cb(stru
+       bool noack = false;
+       cb->flags = 0;
++
++      if (info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP) {
++              cb->flags |= ATH10K_SKB_F_QOS;  /* Assume data frames are QoS */
++              goto finish_cb_fill;
++      }
++
+       if (!ath10k_tx_h_use_hwcrypto(vif, skb))
+               cb->flags |= ATH10K_SKB_F_NO_HWCRYPT;
+@@ -3908,6 +3917,7 @@ static void ath10k_mac_tx_h_fill_cb(stru
+               cb->flags |= ATH10K_SKB_F_RAW_TX;
+       }
++finish_cb_fill:
+       cb->vif = vif;
+       cb->txq = txq;
+       cb->airtime_est = airtime;
+@@ -4031,7 +4041,11 @@ static int ath10k_mac_tx(struct ath10k *
+               ath10k_tx_h_seq_no(vif, skb);
+               break;
+       case ATH10K_HW_TXRX_ETHERNET:
+-              ath10k_tx_h_8023(skb);
++              /* Convert 802.11->802.3 header only if the frame was erlier
++               * encapsulated to 802.11 by mac80211. Otherwise pass it as is.
++               */
++              if (!(info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP))
++                      ath10k_tx_h_8023(skb);
+               break;
+       case ATH10K_HW_TXRX_RAW:
+               if (!test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags) &&
+@@ -4643,12 +4657,10 @@ static void ath10k_mac_op_tx(struct ieee
+       struct ieee80211_vif *vif = info->control.vif;
+       struct ieee80211_sta *sta = control->sta;
+       struct ieee80211_txq *txq = NULL;
+-      struct ieee80211_hdr *hdr = (void *)skb->data;
+       enum ath10k_hw_txrx_mode txmode;
+       enum ath10k_mac_tx_path txpath;
+       bool is_htt;
+       bool is_mgmt;
+-      bool is_presp;
+       int ret;
+       u16 airtime;
+@@ -4662,8 +4674,14 @@ static void ath10k_mac_op_tx(struct ieee
+       is_mgmt = (txpath == ATH10K_MAC_TX_HTT_MGMT);
+       if (is_htt) {
++              bool is_presp = false;
++
+               spin_lock_bh(&ar->htt.tx_lock);
+-              is_presp = ieee80211_is_probe_resp(hdr->frame_control);
++              if (!(info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP)) {
++                      struct ieee80211_hdr *hdr = (void *)skb->data;
++
++                      is_presp = ieee80211_is_probe_resp(hdr->frame_control);
++              }
+               ret = ath10k_htt_tx_inc_pending(htt);
+               if (ret) {
+@@ -5463,6 +5481,30 @@ static int ath10k_mac_set_txbf_conf(stru
+                                        ar->wmi.vdev_param->txbf, value);
+ }
++static void ath10k_update_vif_offload(struct ieee80211_hw *hw,
++                                    struct ieee80211_vif *vif)
++{
++      struct ath10k_vif *arvif = (void *)vif->drv_priv;
++      struct ath10k *ar = hw->priv;
++      u32 vdev_param;
++      int ret;
++
++      if (ath10k_frame_mode != ATH10K_HW_TXRX_ETHERNET ||
++          ar->wmi.vdev_param->tx_encap_type == WMI_VDEV_PARAM_UNSUPPORTED ||
++           (vif->type != NL80211_IFTYPE_STATION &&
++            vif->type != NL80211_IFTYPE_AP))
++              vif->offload_flags &= ~IEEE80211_OFFLOAD_ENCAP_ENABLED;
++
++      vdev_param = ar->wmi.vdev_param->tx_encap_type;
++      ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
++                                      ATH10K_HW_TXRX_NATIVE_WIFI);
++      /* 10.X firmware does not support this VDEV parameter. Do not warn */
++      if (ret && ret != -EOPNOTSUPP) {
++              ath10k_warn(ar, "failed to set vdev %i TX encapsulation: %d\n",
++                          arvif->vdev_id, ret);
++      }
++}
++
+ /*
+  * TODO:
+  * Figure out how to handle WMI_VDEV_SUBTYPE_P2P_DEVICE,
+@@ -5672,15 +5714,7 @@ static int ath10k_add_interface(struct i
+       arvif->def_wep_key_idx = -1;
+-      vdev_param = ar->wmi.vdev_param->tx_encap_type;
+-      ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
+-                                      ATH10K_HW_TXRX_NATIVE_WIFI);
+-      /* 10.X firmware does not support this VDEV parameter. Do not warn */
+-      if (ret && ret != -EOPNOTSUPP) {
+-              ath10k_warn(ar, "failed to set vdev %i TX encapsulation: %d\n",
+-                          arvif->vdev_id, ret);
+-              goto err_vdev_delete;
+-      }
++      ath10k_update_vif_offload(hw, vif);
+       /* Configuring number of spatial stream for monitor interface is causing
+        * target assert in qca9888 and qca6174.
+@@ -9368,6 +9402,7 @@ static const struct ieee80211_ops ath10k
+       .stop                           = ath10k_stop,
+       .config                         = ath10k_config,
+       .add_interface                  = ath10k_add_interface,
++      .update_vif_offload             = ath10k_update_vif_offload,
+       .remove_interface               = ath10k_remove_interface,
+       .configure_filter               = ath10k_configure_filter,
+       .bss_info_changed               = ath10k_bss_info_changed,
+@@ -10037,6 +10072,12 @@ int ath10k_mac_register(struct ath10k *a
+       if (test_bit(WMI_SERVICE_TDLS_UAPSD_BUFFER_STA, ar->wmi.svc_map))
+               ieee80211_hw_set(ar->hw, SUPPORTS_TDLS_BUFFER_STA);
++      if (ath10k_frame_mode == ATH10K_HW_TXRX_ETHERNET) {
++              if (ar->wmi.vdev_param->tx_encap_type !=
++                  WMI_VDEV_PARAM_UNSUPPORTED)
++                      ieee80211_hw_set(ar->hw, SUPPORTS_TX_ENCAP_OFFLOAD);
++      }
++
+       ar->hw->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
+       ar->hw->wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;
+       ar->hw->wiphy->max_remain_on_channel_duration = 5000;
diff --git a/package/kernel/mac80211/patches/ath10k/100-ath10k-support-bus-and-device-specific-API-1-BDF-sel.patch b/package/kernel/mac80211/patches/ath10k/100-ath10k-support-bus-and-device-specific-API-1-BDF-sel.patch
deleted file mode 100644 (file)
index 7ef418e..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-From f2a7064a78b22f2b68b9fcbc8a6f4c5e61c5ba64 Mon Sep 17 00:00:00 2001
-From: Robert Marko <robimarko@gmail.com>
-Date: Sun, 10 Oct 2021 00:17:11 +0200
-Subject: [PATCH] ath10k: support bus and device specific API 1 BDF selection
-
-Some ath10k IPQ40xx devices like the MikroTik hAP ac2 and ac3 require the
-BDF-s to be extracted from the device storage instead of shipping packaged
-API 2 BDF-s.
-
-This is required as MikroTik has started shipping boards that require BDF-s
-to be updated, as otherwise their WLAN performance really suffers.
-This is however impossible as the devices that require this are release
-under the same revision and its not possible to differentiate them from
-devices using the older BDF-s.
-
-In OpenWrt we are extracting the calibration data during runtime and we are
-able to extract the BDF-s in the same manner, however we cannot package the
-BDF-s to API 2 format on the fly and can only use API 1 to provide BDF-s on
-the fly.
-This is an issue as the ath10k driver explicitly looks only for the
-board.bin file and not for something like board-bus-device.bin like it does
-for pre-cal data.
-Due to this we have no way of providing correct BDF-s on the fly, so lets
-extend the ath10k driver to first look for BDF-s in the
-board-bus-device.bin format, for example: board-ahb-a800000.wifi.bin
-If that fails, look for the default board file name as defined previously.
-
-Signed-off-by: Robert Marko <robimarko@gmail.com>
-Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
-Link: https://lore.kernel.org/r/20211009221711.2315352-1-robimarko@gmail.com
----
- drivers/net/wireless/ath/ath10k/core.c | 13 ++++++++++++-
- 1 file changed, 12 insertions(+), 1 deletion(-)
-
---- a/drivers/net/wireless/ath/ath10k/core.c
-+++ b/drivers/net/wireless/ath/ath10k/core.c
-@@ -1202,6 +1202,7 @@ success:
- static int ath10k_core_fetch_board_data_api_1(struct ath10k *ar, int bd_ie_type)
- {
-       const struct firmware *fw;
-+      char boardname[100];
-       if (bd_ie_type == ATH10K_BD_IE_BOARD) {
-               if (!ar->hw_params.fw.board) {
-@@ -1209,9 +1210,19 @@ static int ath10k_core_fetch_board_data_
-                       return -EINVAL;
-               }
-+              scnprintf(boardname, sizeof(boardname), "board-%s-%s.bin",
-+                        ath10k_bus_str(ar->hif.bus), dev_name(ar->dev));
-+
-               ar->normal_mode_fw.board = ath10k_fetch_fw_file(ar,
-                                                               ar->hw_params.fw.dir,
--                                                              ar->hw_params.fw.board);
-+                                                              boardname);
-+              if (IS_ERR(ar->normal_mode_fw.board)) {
-+                      fw = ath10k_fetch_fw_file(ar,
-+                                                ar->hw_params.fw.dir,
-+                                                ar->hw_params.fw.board);
-+                      ar->normal_mode_fw.board = fw;
-+              }
-+
-               if (IS_ERR(ar->normal_mode_fw.board))
-                       return PTR_ERR(ar->normal_mode_fw.board);
diff --git a/package/kernel/mac80211/patches/ath10k/100-v5.19-ath10k-support-bus-and-device-specific-API-1-BDF-sel.patch b/package/kernel/mac80211/patches/ath10k/100-v5.19-ath10k-support-bus-and-device-specific-API-1-BDF-sel.patch
new file mode 100644 (file)
index 0000000..7ef418e
--- /dev/null
@@ -0,0 +1,65 @@
+From f2a7064a78b22f2b68b9fcbc8a6f4c5e61c5ba64 Mon Sep 17 00:00:00 2001
+From: Robert Marko <robimarko@gmail.com>
+Date: Sun, 10 Oct 2021 00:17:11 +0200
+Subject: [PATCH] ath10k: support bus and device specific API 1 BDF selection
+
+Some ath10k IPQ40xx devices like the MikroTik hAP ac2 and ac3 require the
+BDF-s to be extracted from the device storage instead of shipping packaged
+API 2 BDF-s.
+
+This is required as MikroTik has started shipping boards that require BDF-s
+to be updated, as otherwise their WLAN performance really suffers.
+This is however impossible as the devices that require this are release
+under the same revision and its not possible to differentiate them from
+devices using the older BDF-s.
+
+In OpenWrt we are extracting the calibration data during runtime and we are
+able to extract the BDF-s in the same manner, however we cannot package the
+BDF-s to API 2 format on the fly and can only use API 1 to provide BDF-s on
+the fly.
+This is an issue as the ath10k driver explicitly looks only for the
+board.bin file and not for something like board-bus-device.bin like it does
+for pre-cal data.
+Due to this we have no way of providing correct BDF-s on the fly, so lets
+extend the ath10k driver to first look for BDF-s in the
+board-bus-device.bin format, for example: board-ahb-a800000.wifi.bin
+If that fails, look for the default board file name as defined previously.
+
+Signed-off-by: Robert Marko <robimarko@gmail.com>
+Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
+Link: https://lore.kernel.org/r/20211009221711.2315352-1-robimarko@gmail.com
+---
+ drivers/net/wireless/ath/ath10k/core.c | 13 ++++++++++++-
+ 1 file changed, 12 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/wireless/ath/ath10k/core.c
++++ b/drivers/net/wireless/ath/ath10k/core.c
+@@ -1202,6 +1202,7 @@ success:
+ static int ath10k_core_fetch_board_data_api_1(struct ath10k *ar, int bd_ie_type)
+ {
+       const struct firmware *fw;
++      char boardname[100];
+       if (bd_ie_type == ATH10K_BD_IE_BOARD) {
+               if (!ar->hw_params.fw.board) {
+@@ -1209,9 +1210,19 @@ static int ath10k_core_fetch_board_data_
+                       return -EINVAL;
+               }
++              scnprintf(boardname, sizeof(boardname), "board-%s-%s.bin",
++                        ath10k_bus_str(ar->hif.bus), dev_name(ar->dev));
++
+               ar->normal_mode_fw.board = ath10k_fetch_fw_file(ar,
+                                                               ar->hw_params.fw.dir,
+-                                                              ar->hw_params.fw.board);
++                                                              boardname);
++              if (IS_ERR(ar->normal_mode_fw.board)) {
++                      fw = ath10k_fetch_fw_file(ar,
++                                                ar->hw_params.fw.dir,
++                                                ar->hw_params.fw.board);
++                      ar->normal_mode_fw.board = fw;
++              }
++
+               if (IS_ERR(ar->normal_mode_fw.board))
+                       return PTR_ERR(ar->normal_mode_fw.board);
diff --git a/package/kernel/mac80211/patches/ath10k/120-ath10k-fetch-calibration-data-via-nvmem-subsystem.patch b/package/kernel/mac80211/patches/ath10k/120-ath10k-fetch-calibration-data-via-nvmem-subsystem.patch
deleted file mode 100644 (file)
index c7a00b7..0000000
+++ /dev/null
@@ -1,162 +0,0 @@
-From e2333703373e8b81294da5d1c73c30154f75b082 Mon Sep 17 00:00:00 2001
-From: Christian Lamparter <chunkeey@gmail.com>
-Date: Fri, 15 Oct 2021 18:56:33 +0200
-Subject: [PATCH] ath10k: fetch (pre-)calibration data via nvmem subsystem
-
-On most embedded ath10k devices (like range extenders,
-routers, accesspoints, ...) the calibration data is
-stored in a easily accessible MTD partitions named
-"ART", "caldata", "calibration", etc...
-
-Since commit 4b361cfa8624 ("mtd: core: add OTP nvmem provider support"):
-MTD partitions and portions of them can be specified
-as potential nvmem-cells which are accessible through
-the nvmem subsystem.
-
-This feature - together with an nvmem cell definition either
-in the platform data or via device-tree allows drivers to get
-the (pre-)calibration data which is required for initializing
-the WIFI.
-
-Tested with Netgear EX6150v2 (IPQ4018)
-
-Cc: Robert Marko <robimarko@gmail.com>
-Cc: Thibaut Varene <hacks@slashdirt.org>
-Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
----
---- a/drivers/net/wireless/ath/ath10k/core.c
-+++ b/drivers/net/wireless/ath/ath10k/core.c
-@@ -12,6 +12,7 @@
- #include <linux/dmi.h>
- #include <linux/ctype.h>
- #include <linux/pm_qos.h>
-+#include <linux/nvmem-consumer.h>
- #include <asm/byteorder.h>
- #include "core.h"
-@@ -955,7 +956,8 @@ static int ath10k_core_get_board_id_from
-       }
-       if (ar->cal_mode == ATH10K_PRE_CAL_MODE_DT ||
--          ar->cal_mode == ATH10K_PRE_CAL_MODE_FILE)
-+          ar->cal_mode == ATH10K_PRE_CAL_MODE_FILE ||
-+          ar->cal_mode == ATH10K_PRE_CAL_MODE_NVMEM)
-               bmi_board_id_param = BMI_PARAM_GET_FLASH_BOARD_ID;
-       else
-               bmi_board_id_param = BMI_PARAM_GET_EEPROM_BOARD_ID;
-@@ -1757,7 +1759,8 @@ static int ath10k_download_and_run_otp(s
-       /* As of now pre-cal is valid for 10_4 variants */
-       if (ar->cal_mode == ATH10K_PRE_CAL_MODE_DT ||
--          ar->cal_mode == ATH10K_PRE_CAL_MODE_FILE)
-+          ar->cal_mode == ATH10K_PRE_CAL_MODE_FILE ||
-+          ar->cal_mode == ATH10K_PRE_CAL_MODE_NVMEM)
-               bmi_otp_exe_param = BMI_PARAM_FLASH_SECTION_ALL;
-       ret = ath10k_bmi_execute(ar, address, bmi_otp_exe_param, &result);
-@@ -1884,6 +1887,39 @@ out_free:
-       return ret;
- }
-+static int ath10k_download_cal_nvmem(struct ath10k *ar, const char *cell_name)
-+{
-+      struct nvmem_cell *cell;
-+      void *buf;
-+      size_t len;
-+      int ret;
-+
-+      cell = devm_nvmem_cell_get(ar->dev, cell_name);
-+      if (IS_ERR(cell)) {
-+              ret = PTR_ERR(cell);
-+              return ret;
-+      }
-+
-+      buf = nvmem_cell_read(cell, &len);
-+      if (IS_ERR(buf))
-+              return PTR_ERR(buf);
-+
-+      if (ar->hw_params.cal_data_len != len) {
-+              kfree(buf);
-+              ath10k_warn(ar, "invalid calibration data length in nvmem-cell '%s': %zu != %u\n",
-+                          cell_name, len, ar->hw_params.cal_data_len);
-+              return -EMSGSIZE;
-+      }
-+
-+      ret = ath10k_download_board_data(ar, buf, len);
-+      kfree(buf);
-+      if (ret)
-+              ath10k_warn(ar, "failed to download calibration data from nvmem-cell '%s': %d\n",
-+                          cell_name, ret);
-+
-+      return ret;
-+}
-+
- int ath10k_core_fetch_firmware_api_n(struct ath10k *ar, const char *name,
-                                    struct ath10k_fw_file *fw_file)
- {
-@@ -2118,6 +2154,18 @@ static int ath10k_core_pre_cal_download(
- {
-       int ret;
-+      ret = ath10k_download_cal_nvmem(ar, "pre-calibration");
-+      if (ret == 0) {
-+              ar->cal_mode = ATH10K_PRE_CAL_MODE_NVMEM;
-+              goto success;
-+      } else if (ret == -EPROBE_DEFER) {
-+              return ret;
-+      }
-+
-+      ath10k_dbg(ar, ATH10K_DBG_BOOT,
-+                 "boot did not find a pre-calibration nvmem-cell, try file next: %d\n",
-+                 ret);
-+
-       ret = ath10k_download_cal_file(ar, ar->pre_cal_file);
-       if (ret == 0) {
-               ar->cal_mode = ATH10K_PRE_CAL_MODE_FILE;
-@@ -2184,6 +2232,18 @@ static int ath10k_download_cal_data(stru
-                  "pre cal download procedure failed, try cal file: %d\n",
-                  ret);
-+      ret = ath10k_download_cal_nvmem(ar, "calibration");
-+      if (ret == 0) {
-+              ar->cal_mode = ATH10K_CAL_MODE_NVMEM;
-+              goto done;
-+      } else if (ret == -EPROBE_DEFER) {
-+              return ret;
-+      }
-+
-+      ath10k_dbg(ar, ATH10K_DBG_BOOT,
-+                 "boot did not find a calibration nvmem-cell, try file next: %d\n",
-+                 ret);
-+
-       ret = ath10k_download_cal_file(ar, ar->cal_file);
-       if (ret == 0) {
-               ar->cal_mode = ATH10K_CAL_MODE_FILE;
---- a/drivers/net/wireless/ath/ath10k/core.h
-+++ b/drivers/net/wireless/ath/ath10k/core.h
-@@ -877,8 +877,10 @@ enum ath10k_cal_mode {
-       ATH10K_CAL_MODE_FILE,
-       ATH10K_CAL_MODE_OTP,
-       ATH10K_CAL_MODE_DT,
-+      ATH10K_CAL_MODE_NVMEM,
-       ATH10K_PRE_CAL_MODE_FILE,
-       ATH10K_PRE_CAL_MODE_DT,
-+      ATH10K_PRE_CAL_MODE_NVMEM,
-       ATH10K_CAL_MODE_EEPROM,
- };
-@@ -898,10 +900,14 @@ static inline const char *ath10k_cal_mod
-               return "otp";
-       case ATH10K_CAL_MODE_DT:
-               return "dt";
-+      case ATH10K_CAL_MODE_NVMEM:
-+              return "nvmem";
-       case ATH10K_PRE_CAL_MODE_FILE:
-               return "pre-cal-file";
-       case ATH10K_PRE_CAL_MODE_DT:
-               return "pre-cal-dt";
-+      case ATH10K_PRE_CAL_MODE_NVMEM:
-+              return "pre-cal-nvmem";
-       case ATH10K_CAL_MODE_EEPROM:
-               return "eeprom";
-       }
diff --git a/package/kernel/mac80211/patches/ath10k/120-v5.17-ath10k-fetch-calibration-data-via-nvmem-subsystem.patch b/package/kernel/mac80211/patches/ath10k/120-v5.17-ath10k-fetch-calibration-data-via-nvmem-subsystem.patch
new file mode 100644 (file)
index 0000000..c7a00b7
--- /dev/null
@@ -0,0 +1,162 @@
+From e2333703373e8b81294da5d1c73c30154f75b082 Mon Sep 17 00:00:00 2001
+From: Christian Lamparter <chunkeey@gmail.com>
+Date: Fri, 15 Oct 2021 18:56:33 +0200
+Subject: [PATCH] ath10k: fetch (pre-)calibration data via nvmem subsystem
+
+On most embedded ath10k devices (like range extenders,
+routers, accesspoints, ...) the calibration data is
+stored in a easily accessible MTD partitions named
+"ART", "caldata", "calibration", etc...
+
+Since commit 4b361cfa8624 ("mtd: core: add OTP nvmem provider support"):
+MTD partitions and portions of them can be specified
+as potential nvmem-cells which are accessible through
+the nvmem subsystem.
+
+This feature - together with an nvmem cell definition either
+in the platform data or via device-tree allows drivers to get
+the (pre-)calibration data which is required for initializing
+the WIFI.
+
+Tested with Netgear EX6150v2 (IPQ4018)
+
+Cc: Robert Marko <robimarko@gmail.com>
+Cc: Thibaut Varene <hacks@slashdirt.org>
+Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
+---
+--- a/drivers/net/wireless/ath/ath10k/core.c
++++ b/drivers/net/wireless/ath/ath10k/core.c
+@@ -12,6 +12,7 @@
+ #include <linux/dmi.h>
+ #include <linux/ctype.h>
+ #include <linux/pm_qos.h>
++#include <linux/nvmem-consumer.h>
+ #include <asm/byteorder.h>
+ #include "core.h"
+@@ -955,7 +956,8 @@ static int ath10k_core_get_board_id_from
+       }
+       if (ar->cal_mode == ATH10K_PRE_CAL_MODE_DT ||
+-          ar->cal_mode == ATH10K_PRE_CAL_MODE_FILE)
++          ar->cal_mode == ATH10K_PRE_CAL_MODE_FILE ||
++          ar->cal_mode == ATH10K_PRE_CAL_MODE_NVMEM)
+               bmi_board_id_param = BMI_PARAM_GET_FLASH_BOARD_ID;
+       else
+               bmi_board_id_param = BMI_PARAM_GET_EEPROM_BOARD_ID;
+@@ -1757,7 +1759,8 @@ static int ath10k_download_and_run_otp(s
+       /* As of now pre-cal is valid for 10_4 variants */
+       if (ar->cal_mode == ATH10K_PRE_CAL_MODE_DT ||
+-          ar->cal_mode == ATH10K_PRE_CAL_MODE_FILE)
++          ar->cal_mode == ATH10K_PRE_CAL_MODE_FILE ||
++          ar->cal_mode == ATH10K_PRE_CAL_MODE_NVMEM)
+               bmi_otp_exe_param = BMI_PARAM_FLASH_SECTION_ALL;
+       ret = ath10k_bmi_execute(ar, address, bmi_otp_exe_param, &result);
+@@ -1884,6 +1887,39 @@ out_free:
+       return ret;
+ }
++static int ath10k_download_cal_nvmem(struct ath10k *ar, const char *cell_name)
++{
++      struct nvmem_cell *cell;
++      void *buf;
++      size_t len;
++      int ret;
++
++      cell = devm_nvmem_cell_get(ar->dev, cell_name);
++      if (IS_ERR(cell)) {
++              ret = PTR_ERR(cell);
++              return ret;
++      }
++
++      buf = nvmem_cell_read(cell, &len);
++      if (IS_ERR(buf))
++              return PTR_ERR(buf);
++
++      if (ar->hw_params.cal_data_len != len) {
++              kfree(buf);
++              ath10k_warn(ar, "invalid calibration data length in nvmem-cell '%s': %zu != %u\n",
++                          cell_name, len, ar->hw_params.cal_data_len);
++              return -EMSGSIZE;
++      }
++
++      ret = ath10k_download_board_data(ar, buf, len);
++      kfree(buf);
++      if (ret)
++              ath10k_warn(ar, "failed to download calibration data from nvmem-cell '%s': %d\n",
++                          cell_name, ret);
++
++      return ret;
++}
++
+ int ath10k_core_fetch_firmware_api_n(struct ath10k *ar, const char *name,
+                                    struct ath10k_fw_file *fw_file)
+ {
+@@ -2118,6 +2154,18 @@ static int ath10k_core_pre_cal_download(
+ {
+       int ret;
++      ret = ath10k_download_cal_nvmem(ar, "pre-calibration");
++      if (ret == 0) {
++              ar->cal_mode = ATH10K_PRE_CAL_MODE_NVMEM;
++              goto success;
++      } else if (ret == -EPROBE_DEFER) {
++              return ret;
++      }
++
++      ath10k_dbg(ar, ATH10K_DBG_BOOT,
++                 "boot did not find a pre-calibration nvmem-cell, try file next: %d\n",
++                 ret);
++
+       ret = ath10k_download_cal_file(ar, ar->pre_cal_file);
+       if (ret == 0) {
+               ar->cal_mode = ATH10K_PRE_CAL_MODE_FILE;
+@@ -2184,6 +2232,18 @@ static int ath10k_download_cal_data(stru
+                  "pre cal download procedure failed, try cal file: %d\n",
+                  ret);
++      ret = ath10k_download_cal_nvmem(ar, "calibration");
++      if (ret == 0) {
++              ar->cal_mode = ATH10K_CAL_MODE_NVMEM;
++              goto done;
++      } else if (ret == -EPROBE_DEFER) {
++              return ret;
++      }
++
++      ath10k_dbg(ar, ATH10K_DBG_BOOT,
++                 "boot did not find a calibration nvmem-cell, try file next: %d\n",
++                 ret);
++
+       ret = ath10k_download_cal_file(ar, ar->cal_file);
+       if (ret == 0) {
+               ar->cal_mode = ATH10K_CAL_MODE_FILE;
+--- a/drivers/net/wireless/ath/ath10k/core.h
++++ b/drivers/net/wireless/ath/ath10k/core.h
+@@ -877,8 +877,10 @@ enum ath10k_cal_mode {
+       ATH10K_CAL_MODE_FILE,
+       ATH10K_CAL_MODE_OTP,
+       ATH10K_CAL_MODE_DT,
++      ATH10K_CAL_MODE_NVMEM,
+       ATH10K_PRE_CAL_MODE_FILE,
+       ATH10K_PRE_CAL_MODE_DT,
++      ATH10K_PRE_CAL_MODE_NVMEM,
+       ATH10K_CAL_MODE_EEPROM,
+ };
+@@ -898,10 +900,14 @@ static inline const char *ath10k_cal_mod
+               return "otp";
+       case ATH10K_CAL_MODE_DT:
+               return "dt";
++      case ATH10K_CAL_MODE_NVMEM:
++              return "nvmem";
+       case ATH10K_PRE_CAL_MODE_FILE:
+               return "pre-cal-file";
+       case ATH10K_PRE_CAL_MODE_DT:
+               return "pre-cal-dt";
++      case ATH10K_PRE_CAL_MODE_NVMEM:
++              return "pre-cal-nvmem";
+       case ATH10K_CAL_MODE_EEPROM:
+               return "eeprom";
+       }