diff mbox series

[RFC/RFT] ath10k: use xmit encapsulation offloading

Message ID 20220429013319.12728-1-ryazanov.s.a@gmail.com
State New
Headers show
Series [RFC/RFT] ath10k: use xmit encapsulation offloading | expand

Commit Message

Sergey Ryazanov April 29, 2022, 1:33 a.m. UTC
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.

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%).

This change contains a backported series sent upstream [1] and an
additional patch that enables encapsulation offloading by default.

The new feature has been extensively tested with QCA9888 and works well.
Kalle has no objections agains the code, but the lack of tests with
other chips prevents it from being merged [1]. So the improvement is
still in the RFC/RFT state.

Brave testers who would like to improve the performance of their systems
and report their results are welcome :)

1. https://lore.kernel.org/ath10k/20220402153615.9593-1-ryazanov.s.a@gmail.com/

Signed-off-by: Sergey Ryazanov <ryazanov.s.a@gmail.com>
---
 ...1-ath10k-improve-tx-status-reporting.patch |  55 ++++++
 ...-ath10k-turn-rawmode-into-frame_mode.patch |  72 +++++++
 ...add-encapsulation-offloading-support.patch | 186 ++++++++++++++++++
 ...calibration-data-via-nvmem-subsystem.patch |  10 +-
 ...21-ath10k_init_devices_synchronously.patch |   2 +-
 .../930-ath10k_add_tpt_led_trigger.patch      |   4 +-
 ...rolling-support-for-various-chipsets.patch |  16 +-
 ...75-ath10k-use-tpt-trigger-by-default.patch |   2 +-
 ...h10k-Try-to-get-mac-address-from-dts.patch |   2 +-
 ...-encapsulation-offloading-by-default.patch |  11 ++
 10 files changed, 342 insertions(+), 18 deletions(-)
 create mode 100644 package/kernel/mac80211/patches/ath10k/081-ath10k-improve-tx-status-reporting.patch
 create mode 100644 package/kernel/mac80211/patches/ath10k/082-ath10k-turn-rawmode-into-frame_mode.patch
 create mode 100644 package/kernel/mac80211/patches/ath10k/083-ath10k-add-encapsulation-offloading-support.patch
 create mode 100644 package/kernel/mac80211/patches/ath10k/991-ath10k-use-encapsulation-offloading-by-default.patch

Comments

Oldřich Jedlička May 7, 2022, 6:26 a.m. UTC | #1
.Hi Sergey,

pá 29. 4. 2022 v 3:36 odesílatel Sergey Ryazanov
<ryazanov.s.a@gmail.com> napsal:
>
> 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.
>
> 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%).
>
> This change contains a backported series sent upstream [1] and an
> additional patch that enables encapsulation offloading by default.
>
> The new feature has been extensively tested with QCA9888 and works well.
> Kalle has no objections agains the code, but the lack of tests with
> other chips prevents it from being merged [1]. So the improvement is
> still in the RFC/RFT state.
>
> Brave testers who would like to improve the performance of their systems
> and report their results are welcome :)
>
> 1. https://lore.kernel.org/ath10k/20220402153615.9593-1-ryazanov.s.a@gmail.com/
>

I am using your patch for two days. I am not able to tell whether it
does anything with regards to speed (I have not done any performance
tests for comparison), but at least it does not break the internet
connection, which is good :-)

Tested on Archer C7 v4 (2x) and v5 (2x), both versions contain QCA9563
+ QCA9880.

Regards
Olda.

> Signed-off-by: Sergey Ryazanov <ryazanov.s.a@gmail.com>
> ---
>  ...1-ath10k-improve-tx-status-reporting.patch |  55 ++++++
>  ...-ath10k-turn-rawmode-into-frame_mode.patch |  72 +++++++
>  ...add-encapsulation-offloading-support.patch | 186 ++++++++++++++++++
>  ...calibration-data-via-nvmem-subsystem.patch |  10 +-
>  ...21-ath10k_init_devices_synchronously.patch |   2 +-
>  .../930-ath10k_add_tpt_led_trigger.patch      |   4 +-
>  ...rolling-support-for-various-chipsets.patch |  16 +-
>  ...75-ath10k-use-tpt-trigger-by-default.patch |   2 +-
>  ...h10k-Try-to-get-mac-address-from-dts.patch |   2 +-
>  ...-encapsulation-offloading-by-default.patch |  11 ++
>  10 files changed, 342 insertions(+), 18 deletions(-)
>  create mode 100644 package/kernel/mac80211/patches/ath10k/081-ath10k-improve-tx-status-reporting.patch
>  create mode 100644 package/kernel/mac80211/patches/ath10k/082-ath10k-turn-rawmode-into-frame_mode.patch
>  create mode 100644 package/kernel/mac80211/patches/ath10k/083-ath10k-add-encapsulation-offloading-support.patch
>  create mode 100644 package/kernel/mac80211/patches/ath10k/991-ath10k-use-encapsulation-offloading-by-default.patch
>
> diff --git a/package/kernel/mac80211/patches/ath10k/081-ath10k-improve-tx-status-reporting.patch b/package/kernel/mac80211/patches/ath10k/081-ath10k-improve-tx-status-reporting.patch
> new file mode 100644
> index 0000000000..1a0915a460
> --- /dev/null
> +++ b/package/kernel/mac80211/patches/ath10k/081-ath10k-improve-tx-status-reporting.patch
> @@ -0,0 +1,55 @@
> +From 018de7ad86697d2924677a2a7725331561c03fe0 Mon Sep 17 00:00:00 2001
> +From: Sergey Ryazanov <ryazanov.s.a@gmail.com>
> +Date: Sat, 2 Apr 2022 02:37:34 +0300
> +Subject: [PATCH RFC 1/3] ath10k: improve tx status reporting
> +
> +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 hw 2.0 10.4-3.9.0.2-00131
> +Signed-off-by: Sergey Ryazanov <ryazanov.s.a@gmail.com>
> +---
> + drivers/net/wireless/ath/ath10k/txrx.c | 12 +++++++++++-
> + 1 file changed, 11 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,16 @@ 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 && txq->sta)
> ++              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/082-ath10k-turn-rawmode-into-frame_mode.patch b/package/kernel/mac80211/patches/ath10k/082-ath10k-turn-rawmode-into-frame_mode.patch
> new file mode 100644
> index 0000000000..db82d236ff
> --- /dev/null
> +++ b/package/kernel/mac80211/patches/ath10k/082-ath10k-turn-rawmode-into-frame_mode.patch
> @@ -0,0 +1,72 @@
> +From 4843b08e42794f7405efabb73d20ee0d33113822 Mon Sep 17 00:00:00 2001
> +From: Sergey Ryazanov <ryazanov.s.a@gmail.com>
> +Date: Sat, 2 Apr 2022 02:42:10 +0300
> +Subject: [PATCH RFC 2/3] 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>
> +---
> + 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/083-ath10k-add-encapsulation-offloading-support.patch b/package/kernel/mac80211/patches/ath10k/083-ath10k-add-encapsulation-offloading-support.patch
> new file mode 100644
> index 0000000000..96b4e8b4af
> --- /dev/null
> +++ b/package/kernel/mac80211/patches/ath10k/083-ath10k-add-encapsulation-offloading-support.patch
> @@ -0,0 +1,186 @@
> +From 20bf0e61ee430b836a6cd3f2b88b46adb4c3e107 Mon Sep 17 00:00:00 2001
> +From: Sergey Ryazanov <ryazanov.s.a@gmail.com>
> +Date: Sat, 2 Apr 2022 02:45:52 +0300
> +In-Reply-To: <20220402153615.9593-1-ryazanov.s.a@gmail.com>
> +References: <20220402153615.9593-1-ryazanov.s.a@gmail.com>
> +Subject: [PATCH RFC 3/3] ath10k: add encapsulation offloading support
> +
> +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 hw 2.0 10.4-3.9.0.2-00131
> +Signed-off-by: Sergey Ryazanov <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) {
> +@@ -5447,6 +5465,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,
> +@@ -5656,15 +5698,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.
> +@@ -9352,6 +9386,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,
> +@@ -10021,6 +10056,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/120-ath10k-fetch-calibration-data-via-nvmem-subsystem.patch b/package/kernel/mac80211/patches/ath10k/120-ath10k-fetch-calibration-data-via-nvmem-subsystem.patch
> index bebd5fe6c2..730e3ccb31 100644
> --- 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
> @@ -34,7 +34,7 @@ Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
>   #include <asm/byteorder.h>
>
>   #include "core.h"
> -@@ -952,7 +953,8 @@ static int ath10k_core_get_board_id_from
> +@@ -955,7 +956,8 @@ static int ath10k_core_get_board_id_from
>         }
>
>         if (ar->cal_mode == ATH10K_PRE_CAL_MODE_DT ||
> @@ -44,7 +44,7 @@ Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
>                 bmi_board_id_param = BMI_PARAM_GET_FLASH_BOARD_ID;
>         else
>                 bmi_board_id_param = BMI_PARAM_GET_EEPROM_BOARD_ID;
> -@@ -1743,7 +1745,8 @@ static int ath10k_download_and_run_otp(s
> +@@ -1746,7 +1748,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 ||
> @@ -54,7 +54,7 @@ Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
>                 bmi_otp_exe_param = BMI_PARAM_FLASH_SECTION_ALL;
>
>         ret = ath10k_bmi_execute(ar, address, bmi_otp_exe_param, &result);
> -@@ -1870,6 +1873,39 @@ out_free:
> +@@ -1873,6 +1876,39 @@ out_free:
>         return ret;
>   }
>
> @@ -94,7 +94,7 @@ Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
>   int ath10k_core_fetch_firmware_api_n(struct ath10k *ar, const char *name,
>                                      struct ath10k_fw_file *fw_file)
>   {
> -@@ -2104,6 +2140,18 @@ static int ath10k_core_pre_cal_download(
> +@@ -2107,6 +2143,18 @@ static int ath10k_core_pre_cal_download(
>   {
>         int ret;
>
> @@ -113,7 +113,7 @@ Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
>         ret = ath10k_download_cal_file(ar, ar->pre_cal_file);
>         if (ret == 0) {
>                 ar->cal_mode = ATH10K_PRE_CAL_MODE_FILE;
> -@@ -2170,6 +2218,18 @@ static int ath10k_download_cal_data(stru
> +@@ -2173,6 +2221,18 @@ static int ath10k_download_cal_data(stru
>                    "pre cal download procedure failed, try cal file: %d\n",
>                    ret);
>
> diff --git a/package/kernel/mac80211/patches/ath10k/921-ath10k_init_devices_synchronously.patch b/package/kernel/mac80211/patches/ath10k/921-ath10k_init_devices_synchronously.patch
> index b6ae2c7c83..ea0b008430 100644
> --- a/package/kernel/mac80211/patches/ath10k/921-ath10k_init_devices_synchronously.patch
> +++ b/package/kernel/mac80211/patches/ath10k/921-ath10k_init_devices_synchronously.patch
> @@ -14,7 +14,7 @@ Signed-off-by: Sven Eckelmann <sven@open-mesh.com>
>
>  --- a/drivers/net/wireless/ath/ath10k/core.c
>  +++ b/drivers/net/wireless/ath/ath10k/core.c
> -@@ -3429,6 +3429,16 @@ int ath10k_core_register(struct ath10k *
> +@@ -3432,6 +3432,16 @@ int ath10k_core_register(struct ath10k *
>
>         queue_work(ar->workqueue, &ar->register_work);
>
> diff --git a/package/kernel/mac80211/patches/ath10k/930-ath10k_add_tpt_led_trigger.patch b/package/kernel/mac80211/patches/ath10k/930-ath10k_add_tpt_led_trigger.patch
> index b60db19464..9cbc52b88f 100644
> --- a/package/kernel/mac80211/patches/ath10k/930-ath10k_add_tpt_led_trigger.patch
> +++ b/package/kernel/mac80211/patches/ath10k/930-ath10k_add_tpt_led_trigger.patch
> @@ -1,6 +1,6 @@
>  --- a/drivers/net/wireless/ath/ath10k/mac.c
>  +++ b/drivers/net/wireless/ath/ath10k/mac.c
> -@@ -9843,6 +9843,21 @@ static int ath10k_mac_init_rd(struct ath
> +@@ -9878,6 +9878,21 @@ static int ath10k_mac_init_rd(struct ath
>         return 0;
>   }
>
> @@ -22,7 +22,7 @@
>   int ath10k_mac_register(struct ath10k *ar)
>   {
>         static const u32 cipher_suites[] = {
> -@@ -10195,6 +10210,12 @@ int ath10k_mac_register(struct ath10k *a
> +@@ -10236,6 +10251,12 @@ int ath10k_mac_register(struct ath10k *a
>
>         ar->hw->weight_multiplier = ATH10K_AIRTIME_WEIGHT_MULTIPLIER;
>
> diff --git a/package/kernel/mac80211/patches/ath10k/974-ath10k_add-LED-and-GPIO-controlling-support-for-various-chipsets.patch b/package/kernel/mac80211/patches/ath10k/974-ath10k_add-LED-and-GPIO-controlling-support-for-various-chipsets.patch
> index 6db2430749..1440b94a78 100644
> --- a/package/kernel/mac80211/patches/ath10k/974-ath10k_add-LED-and-GPIO-controlling-support-for-various-chipsets.patch
> +++ b/package/kernel/mac80211/patches/ath10k/974-ath10k_add-LED-and-GPIO-controlling-support-for-various-chipsets.patch
> @@ -132,7 +132,7 @@ v13:
>
>   unsigned int ath10k_debug_mask;
>   EXPORT_SYMBOL(ath10k_debug_mask);
> -@@ -62,6 +63,7 @@ static const struct ath10k_hw_params ath
> +@@ -65,6 +66,7 @@ static const struct ath10k_hw_params ath
>                 .dev_id = QCA988X_2_0_DEVICE_ID,
>                 .bus = ATH10K_BUS_PCI,
>                 .name = "qca988x hw2.0",
> @@ -140,7 +140,7 @@ v13:
>                 .patch_load_addr = QCA988X_HW_2_0_PATCH_LOAD_ADDR,
>                 .uart_pin = 7,
>                 .cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_ALL,
> -@@ -135,6 +137,7 @@ static const struct ath10k_hw_params ath
> +@@ -138,6 +140,7 @@ static const struct ath10k_hw_params ath
>                 .dev_id = QCA9887_1_0_DEVICE_ID,
>                 .bus = ATH10K_BUS_PCI,
>                 .name = "qca9887 hw1.0",
> @@ -148,7 +148,7 @@ v13:
>                 .patch_load_addr = QCA9887_HW_1_0_PATCH_LOAD_ADDR,
>                 .uart_pin = 7,
>                 .cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_ALL,
> -@@ -352,6 +355,7 @@ static const struct ath10k_hw_params ath
> +@@ -355,6 +358,7 @@ static const struct ath10k_hw_params ath
>                 .dev_id = QCA99X0_2_0_DEVICE_ID,
>                 .bus = ATH10K_BUS_PCI,
>                 .name = "qca99x0 hw2.0",
> @@ -156,7 +156,7 @@ v13:
>                 .patch_load_addr = QCA99X0_HW_2_0_PATCH_LOAD_ADDR,
>                 .uart_pin = 7,
>                 .otp_exe_param = 0x00000700,
> -@@ -394,6 +398,7 @@ static const struct ath10k_hw_params ath
> +@@ -397,6 +401,7 @@ static const struct ath10k_hw_params ath
>                 .dev_id = QCA9984_1_0_DEVICE_ID,
>                 .bus = ATH10K_BUS_PCI,
>                 .name = "qca9984/qca9994 hw1.0",
> @@ -164,7 +164,7 @@ v13:
>                 .patch_load_addr = QCA9984_HW_1_0_PATCH_LOAD_ADDR,
>                 .uart_pin = 7,
>                 .cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_EACH,
> -@@ -443,6 +448,7 @@ static const struct ath10k_hw_params ath
> +@@ -446,6 +451,7 @@ static const struct ath10k_hw_params ath
>                 .dev_id = QCA9888_2_0_DEVICE_ID,
>                 .bus = ATH10K_BUS_PCI,
>                 .name = "qca9888 hw2.0",
> @@ -172,7 +172,7 @@ v13:
>                 .patch_load_addr = QCA9888_HW_2_0_PATCH_LOAD_ADDR,
>                 .uart_pin = 7,
>                 .cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_EACH,
> -@@ -3144,6 +3150,10 @@ int ath10k_core_start(struct ath10k *ar,
> +@@ -3147,6 +3153,10 @@ int ath10k_core_start(struct ath10k *ar,
>                 goto err_hif_stop;
>         }
>
> @@ -183,7 +183,7 @@ v13:
>         return 0;
>
>   err_hif_stop:
> -@@ -3402,9 +3412,18 @@ static void ath10k_core_register_work(st
> +@@ -3405,9 +3415,18 @@ static void ath10k_core_register_work(st
>                 goto err_spectral_destroy;
>         }
>
> @@ -202,7 +202,7 @@ v13:
>   err_spectral_destroy:
>         ath10k_spectral_destroy(ar);
>   err_debug_destroy:
> -@@ -3450,6 +3469,8 @@ void ath10k_core_unregister(struct ath10
> +@@ -3453,6 +3472,8 @@ void ath10k_core_unregister(struct ath10
>         if (!test_bit(ATH10K_FLAG_CORE_REGISTERED, &ar->dev_flags))
>                 return;
>
> diff --git a/package/kernel/mac80211/patches/ath10k/975-ath10k-use-tpt-trigger-by-default.patch b/package/kernel/mac80211/patches/ath10k/975-ath10k-use-tpt-trigger-by-default.patch
> index da31ad578a..4c1b73b1c1 100644
> --- a/package/kernel/mac80211/patches/ath10k/975-ath10k-use-tpt-trigger-by-default.patch
> +++ b/package/kernel/mac80211/patches/ath10k/975-ath10k-use-tpt-trigger-by-default.patch
> @@ -42,7 +42,7 @@ Signed-off-by: Mathias Kresin <dev@kresin.me>
>         if (ret)
>  --- a/drivers/net/wireless/ath/ath10k/mac.c
>  +++ b/drivers/net/wireless/ath/ath10k/mac.c
> -@@ -10212,7 +10212,7 @@ int ath10k_mac_register(struct ath10k *a
> +@@ -10253,7 +10253,7 @@ int ath10k_mac_register(struct ath10k *a
>         ar->hw->weight_multiplier = ATH10K_AIRTIME_WEIGHT_MULTIPLIER;
>
>   #ifdef CPTCFG_MAC80211_LEDS
> diff --git a/package/kernel/mac80211/patches/ath10k/984-ath10k-Try-to-get-mac-address-from-dts.patch b/package/kernel/mac80211/patches/ath10k/984-ath10k-Try-to-get-mac-address-from-dts.patch
> index 4077b2f393..724094010e 100644
> --- a/package/kernel/mac80211/patches/ath10k/984-ath10k-Try-to-get-mac-address-from-dts.patch
> +++ b/package/kernel/mac80211/patches/ath10k/984-ath10k-Try-to-get-mac-address-from-dts.patch
> @@ -26,7 +26,7 @@ Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
>   #include <linux/property.h>
>   #include <linux/dmi.h>
>   #include <linux/ctype.h>
> -@@ -3320,6 +3321,8 @@ static int ath10k_core_probe_fw(struct a
> +@@ -3323,6 +3324,8 @@ static int ath10k_core_probe_fw(struct a
>
>         device_get_mac_address(ar->dev, ar->mac_addr, sizeof(ar->mac_addr));
>
> diff --git a/package/kernel/mac80211/patches/ath10k/991-ath10k-use-encapsulation-offloading-by-default.patch b/package/kernel/mac80211/patches/ath10k/991-ath10k-use-encapsulation-offloading-by-default.patch
> new file mode 100644
> index 0000000000..2218155d32
> --- /dev/null
> +++ b/package/kernel/mac80211/patches/ath10k/991-ath10k-use-encapsulation-offloading-by-default.patch
> @@ -0,0 +1,11 @@
> +--- a/drivers/net/wireless/ath/ath10k/core.c
> ++++ b/drivers/net/wireless/ath/ath10k/core.c
> +@@ -38,7 +38,7 @@ static bool skip_otp;
> + 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 int ath10k_frame_mode = ATH10K_HW_TXRX_ETHERNET;
> +
> + unsigned long ath10k_coredump_mask = BIT(ATH10K_FW_CRASH_DUMP_REGISTERS) |
> +                                    BIT(ATH10K_FW_CRASH_DUMP_CE_DATA);
> --
> 2.35.1
>
Sergey Ryazanov May 7, 2022, 9:21 a.m. UTC | #2
Hello Oldřich,

On Sat, May 7, 2022 at 9:27 AM Oldřich Jedlička <oldium.pro@gmail.com> wrote:
> .Hi Sergey,
>
> pá 29. 4. 2022 v 3:36 odesílatel Sergey Ryazanov
> <ryazanov.s.a@gmail.com> napsal:
>>
>> 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.
>>
>> 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%).
>>
>> This change contains a backported series sent upstream [1] and an
>> additional patch that enables encapsulation offloading by default.
>>
>> The new feature has been extensively tested with QCA9888 and works well.
>> Kalle has no objections agains the code, but the lack of tests with
>> other chips prevents it from being merged [1]. So the improvement is
>> still in the RFC/RFT state.
>>
>> Brave testers who would like to improve the performance of their systems
>> and report their results are welcome :)
>>
>> 1. https://lore.kernel.org/ath10k/20220402153615.9593-1-ryazanov.s.a@gmail.com/
>>
>
> I am using your patch for two days. I am not able to tell whether it
> does anything with regards to speed (I have not done any performance
> tests for comparison), but at least it does not break the internet
> connection, which is good :-)
>
> Tested on Archer C7 v4 (2x) and v5 (2x), both versions contain QCA9563
> + QCA9880.

Too many thanks for testing it!
Sergey Ryazanov May 13, 2022, 10:16 p.m. UTC | #3
Hello Oldřich and Edward,

Thank you once more for testing these changes. I additionally tested
QCA6174 and now I am ready to send a formal patch. May I use your
'tested-by' in subsequent submissions?
Oldřich Jedlička May 14, 2022, 6:58 p.m. UTC | #4
so 14. 5. 2022 v 0:16 odesílatel Sergey Ryazanov
<ryazanov.s.a@gmail.com> napsal:
>
> Hello Oldřich and Edward,
>
> Thank you once more for testing these changes. I additionally tested
> QCA6174 and now I am ready to send a formal patch. May I use your
> 'tested-by' in subsequent submissions?

Yes, sure.

Tested-by: Oldřich Jedlička <oldium.pro@gmail.com>

>
> --
> Sergey
diff mbox series

Patch

diff --git a/package/kernel/mac80211/patches/ath10k/081-ath10k-improve-tx-status-reporting.patch b/package/kernel/mac80211/patches/ath10k/081-ath10k-improve-tx-status-reporting.patch
new file mode 100644
index 0000000000..1a0915a460
--- /dev/null
+++ b/package/kernel/mac80211/patches/ath10k/081-ath10k-improve-tx-status-reporting.patch
@@ -0,0 +1,55 @@ 
+From 018de7ad86697d2924677a2a7725331561c03fe0 Mon Sep 17 00:00:00 2001
+From: Sergey Ryazanov <ryazanov.s.a@gmail.com>
+Date: Sat, 2 Apr 2022 02:37:34 +0300
+Subject: [PATCH RFC 1/3] ath10k: improve tx status reporting
+
+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 hw 2.0 10.4-3.9.0.2-00131
+Signed-off-by: Sergey Ryazanov <ryazanov.s.a@gmail.com>
+---
+ drivers/net/wireless/ath/ath10k/txrx.c | 12 +++++++++++-
+ 1 file changed, 11 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,16 @@ 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 && txq->sta)
++		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/082-ath10k-turn-rawmode-into-frame_mode.patch b/package/kernel/mac80211/patches/ath10k/082-ath10k-turn-rawmode-into-frame_mode.patch
new file mode 100644
index 0000000000..db82d236ff
--- /dev/null
+++ b/package/kernel/mac80211/patches/ath10k/082-ath10k-turn-rawmode-into-frame_mode.patch
@@ -0,0 +1,72 @@ 
+From 4843b08e42794f7405efabb73d20ee0d33113822 Mon Sep 17 00:00:00 2001
+From: Sergey Ryazanov <ryazanov.s.a@gmail.com>
+Date: Sat, 2 Apr 2022 02:42:10 +0300
+Subject: [PATCH RFC 2/3] 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>
+---
+ 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/083-ath10k-add-encapsulation-offloading-support.patch b/package/kernel/mac80211/patches/ath10k/083-ath10k-add-encapsulation-offloading-support.patch
new file mode 100644
index 0000000000..96b4e8b4af
--- /dev/null
+++ b/package/kernel/mac80211/patches/ath10k/083-ath10k-add-encapsulation-offloading-support.patch
@@ -0,0 +1,186 @@ 
+From 20bf0e61ee430b836a6cd3f2b88b46adb4c3e107 Mon Sep 17 00:00:00 2001
+From: Sergey Ryazanov <ryazanov.s.a@gmail.com>
+Date: Sat, 2 Apr 2022 02:45:52 +0300
+In-Reply-To: <20220402153615.9593-1-ryazanov.s.a@gmail.com>
+References: <20220402153615.9593-1-ryazanov.s.a@gmail.com>
+Subject: [PATCH RFC 3/3] ath10k: add encapsulation offloading support
+
+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 hw 2.0 10.4-3.9.0.2-00131
+Signed-off-by: Sergey Ryazanov <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) {
+@@ -5447,6 +5465,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,
+@@ -5656,15 +5698,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.
+@@ -9352,6 +9386,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,
+@@ -10021,6 +10056,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/120-ath10k-fetch-calibration-data-via-nvmem-subsystem.patch b/package/kernel/mac80211/patches/ath10k/120-ath10k-fetch-calibration-data-via-nvmem-subsystem.patch
index bebd5fe6c2..730e3ccb31 100644
--- 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
@@ -34,7 +34,7 @@  Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
  #include <asm/byteorder.h>
  
  #include "core.h"
-@@ -952,7 +953,8 @@ static int ath10k_core_get_board_id_from
+@@ -955,7 +956,8 @@ static int ath10k_core_get_board_id_from
  	}
  
  	if (ar->cal_mode == ATH10K_PRE_CAL_MODE_DT ||
@@ -44,7 +44,7 @@  Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
  		bmi_board_id_param = BMI_PARAM_GET_FLASH_BOARD_ID;
  	else
  		bmi_board_id_param = BMI_PARAM_GET_EEPROM_BOARD_ID;
-@@ -1743,7 +1745,8 @@ static int ath10k_download_and_run_otp(s
+@@ -1746,7 +1748,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 ||
@@ -54,7 +54,7 @@  Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
  		bmi_otp_exe_param = BMI_PARAM_FLASH_SECTION_ALL;
  
  	ret = ath10k_bmi_execute(ar, address, bmi_otp_exe_param, &result);
-@@ -1870,6 +1873,39 @@ out_free:
+@@ -1873,6 +1876,39 @@ out_free:
  	return ret;
  }
  
@@ -94,7 +94,7 @@  Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
  int ath10k_core_fetch_firmware_api_n(struct ath10k *ar, const char *name,
  				     struct ath10k_fw_file *fw_file)
  {
-@@ -2104,6 +2140,18 @@ static int ath10k_core_pre_cal_download(
+@@ -2107,6 +2143,18 @@ static int ath10k_core_pre_cal_download(
  {
  	int ret;
  
@@ -113,7 +113,7 @@  Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
  	ret = ath10k_download_cal_file(ar, ar->pre_cal_file);
  	if (ret == 0) {
  		ar->cal_mode = ATH10K_PRE_CAL_MODE_FILE;
-@@ -2170,6 +2218,18 @@ static int ath10k_download_cal_data(stru
+@@ -2173,6 +2221,18 @@ static int ath10k_download_cal_data(stru
  		   "pre cal download procedure failed, try cal file: %d\n",
  		   ret);
  
diff --git a/package/kernel/mac80211/patches/ath10k/921-ath10k_init_devices_synchronously.patch b/package/kernel/mac80211/patches/ath10k/921-ath10k_init_devices_synchronously.patch
index b6ae2c7c83..ea0b008430 100644
--- a/package/kernel/mac80211/patches/ath10k/921-ath10k_init_devices_synchronously.patch
+++ b/package/kernel/mac80211/patches/ath10k/921-ath10k_init_devices_synchronously.patch
@@ -14,7 +14,7 @@  Signed-off-by: Sven Eckelmann <sven@open-mesh.com>
 
 --- a/drivers/net/wireless/ath/ath10k/core.c
 +++ b/drivers/net/wireless/ath/ath10k/core.c
-@@ -3429,6 +3429,16 @@ int ath10k_core_register(struct ath10k *
+@@ -3432,6 +3432,16 @@ int ath10k_core_register(struct ath10k *
  
  	queue_work(ar->workqueue, &ar->register_work);
  
diff --git a/package/kernel/mac80211/patches/ath10k/930-ath10k_add_tpt_led_trigger.patch b/package/kernel/mac80211/patches/ath10k/930-ath10k_add_tpt_led_trigger.patch
index b60db19464..9cbc52b88f 100644
--- a/package/kernel/mac80211/patches/ath10k/930-ath10k_add_tpt_led_trigger.patch
+++ b/package/kernel/mac80211/patches/ath10k/930-ath10k_add_tpt_led_trigger.patch
@@ -1,6 +1,6 @@ 
 --- a/drivers/net/wireless/ath/ath10k/mac.c
 +++ b/drivers/net/wireless/ath/ath10k/mac.c
-@@ -9843,6 +9843,21 @@ static int ath10k_mac_init_rd(struct ath
+@@ -9878,6 +9878,21 @@ static int ath10k_mac_init_rd(struct ath
  	return 0;
  }
  
@@ -22,7 +22,7 @@ 
  int ath10k_mac_register(struct ath10k *ar)
  {
  	static const u32 cipher_suites[] = {
-@@ -10195,6 +10210,12 @@ int ath10k_mac_register(struct ath10k *a
+@@ -10236,6 +10251,12 @@ int ath10k_mac_register(struct ath10k *a
  
  	ar->hw->weight_multiplier = ATH10K_AIRTIME_WEIGHT_MULTIPLIER;
  
diff --git a/package/kernel/mac80211/patches/ath10k/974-ath10k_add-LED-and-GPIO-controlling-support-for-various-chipsets.patch b/package/kernel/mac80211/patches/ath10k/974-ath10k_add-LED-and-GPIO-controlling-support-for-various-chipsets.patch
index 6db2430749..1440b94a78 100644
--- a/package/kernel/mac80211/patches/ath10k/974-ath10k_add-LED-and-GPIO-controlling-support-for-various-chipsets.patch
+++ b/package/kernel/mac80211/patches/ath10k/974-ath10k_add-LED-and-GPIO-controlling-support-for-various-chipsets.patch
@@ -132,7 +132,7 @@  v13:
  
  unsigned int ath10k_debug_mask;
  EXPORT_SYMBOL(ath10k_debug_mask);
-@@ -62,6 +63,7 @@ static const struct ath10k_hw_params ath
+@@ -65,6 +66,7 @@ static const struct ath10k_hw_params ath
  		.dev_id = QCA988X_2_0_DEVICE_ID,
  		.bus = ATH10K_BUS_PCI,
  		.name = "qca988x hw2.0",
@@ -140,7 +140,7 @@  v13:
  		.patch_load_addr = QCA988X_HW_2_0_PATCH_LOAD_ADDR,
  		.uart_pin = 7,
  		.cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_ALL,
-@@ -135,6 +137,7 @@ static const struct ath10k_hw_params ath
+@@ -138,6 +140,7 @@ static const struct ath10k_hw_params ath
  		.dev_id = QCA9887_1_0_DEVICE_ID,
  		.bus = ATH10K_BUS_PCI,
  		.name = "qca9887 hw1.0",
@@ -148,7 +148,7 @@  v13:
  		.patch_load_addr = QCA9887_HW_1_0_PATCH_LOAD_ADDR,
  		.uart_pin = 7,
  		.cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_ALL,
-@@ -352,6 +355,7 @@ static const struct ath10k_hw_params ath
+@@ -355,6 +358,7 @@ static const struct ath10k_hw_params ath
  		.dev_id = QCA99X0_2_0_DEVICE_ID,
  		.bus = ATH10K_BUS_PCI,
  		.name = "qca99x0 hw2.0",
@@ -156,7 +156,7 @@  v13:
  		.patch_load_addr = QCA99X0_HW_2_0_PATCH_LOAD_ADDR,
  		.uart_pin = 7,
  		.otp_exe_param = 0x00000700,
-@@ -394,6 +398,7 @@ static const struct ath10k_hw_params ath
+@@ -397,6 +401,7 @@ static const struct ath10k_hw_params ath
  		.dev_id = QCA9984_1_0_DEVICE_ID,
  		.bus = ATH10K_BUS_PCI,
  		.name = "qca9984/qca9994 hw1.0",
@@ -164,7 +164,7 @@  v13:
  		.patch_load_addr = QCA9984_HW_1_0_PATCH_LOAD_ADDR,
  		.uart_pin = 7,
  		.cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_EACH,
-@@ -443,6 +448,7 @@ static const struct ath10k_hw_params ath
+@@ -446,6 +451,7 @@ static const struct ath10k_hw_params ath
  		.dev_id = QCA9888_2_0_DEVICE_ID,
  		.bus = ATH10K_BUS_PCI,
  		.name = "qca9888 hw2.0",
@@ -172,7 +172,7 @@  v13:
  		.patch_load_addr = QCA9888_HW_2_0_PATCH_LOAD_ADDR,
  		.uart_pin = 7,
  		.cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_EACH,
-@@ -3144,6 +3150,10 @@ int ath10k_core_start(struct ath10k *ar,
+@@ -3147,6 +3153,10 @@ int ath10k_core_start(struct ath10k *ar,
  		goto err_hif_stop;
  	}
  
@@ -183,7 +183,7 @@  v13:
  	return 0;
  
  err_hif_stop:
-@@ -3402,9 +3412,18 @@ static void ath10k_core_register_work(st
+@@ -3405,9 +3415,18 @@ static void ath10k_core_register_work(st
  		goto err_spectral_destroy;
  	}
  
@@ -202,7 +202,7 @@  v13:
  err_spectral_destroy:
  	ath10k_spectral_destroy(ar);
  err_debug_destroy:
-@@ -3450,6 +3469,8 @@ void ath10k_core_unregister(struct ath10
+@@ -3453,6 +3472,8 @@ void ath10k_core_unregister(struct ath10
  	if (!test_bit(ATH10K_FLAG_CORE_REGISTERED, &ar->dev_flags))
  		return;
  
diff --git a/package/kernel/mac80211/patches/ath10k/975-ath10k-use-tpt-trigger-by-default.patch b/package/kernel/mac80211/patches/ath10k/975-ath10k-use-tpt-trigger-by-default.patch
index da31ad578a..4c1b73b1c1 100644
--- a/package/kernel/mac80211/patches/ath10k/975-ath10k-use-tpt-trigger-by-default.patch
+++ b/package/kernel/mac80211/patches/ath10k/975-ath10k-use-tpt-trigger-by-default.patch
@@ -42,7 +42,7 @@  Signed-off-by: Mathias Kresin <dev@kresin.me>
  	if (ret)
 --- a/drivers/net/wireless/ath/ath10k/mac.c
 +++ b/drivers/net/wireless/ath/ath10k/mac.c
-@@ -10212,7 +10212,7 @@ int ath10k_mac_register(struct ath10k *a
+@@ -10253,7 +10253,7 @@ int ath10k_mac_register(struct ath10k *a
  	ar->hw->weight_multiplier = ATH10K_AIRTIME_WEIGHT_MULTIPLIER;
  
  #ifdef CPTCFG_MAC80211_LEDS
diff --git a/package/kernel/mac80211/patches/ath10k/984-ath10k-Try-to-get-mac-address-from-dts.patch b/package/kernel/mac80211/patches/ath10k/984-ath10k-Try-to-get-mac-address-from-dts.patch
index 4077b2f393..724094010e 100644
--- a/package/kernel/mac80211/patches/ath10k/984-ath10k-Try-to-get-mac-address-from-dts.patch
+++ b/package/kernel/mac80211/patches/ath10k/984-ath10k-Try-to-get-mac-address-from-dts.patch
@@ -26,7 +26,7 @@  Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
  #include <linux/property.h>
  #include <linux/dmi.h>
  #include <linux/ctype.h>
-@@ -3320,6 +3321,8 @@ static int ath10k_core_probe_fw(struct a
+@@ -3323,6 +3324,8 @@ static int ath10k_core_probe_fw(struct a
  
  	device_get_mac_address(ar->dev, ar->mac_addr, sizeof(ar->mac_addr));
  
diff --git a/package/kernel/mac80211/patches/ath10k/991-ath10k-use-encapsulation-offloading-by-default.patch b/package/kernel/mac80211/patches/ath10k/991-ath10k-use-encapsulation-offloading-by-default.patch
new file mode 100644
index 0000000000..2218155d32
--- /dev/null
+++ b/package/kernel/mac80211/patches/ath10k/991-ath10k-use-encapsulation-offloading-by-default.patch
@@ -0,0 +1,11 @@ 
+--- a/drivers/net/wireless/ath/ath10k/core.c
++++ b/drivers/net/wireless/ath/ath10k/core.c
+@@ -38,7 +38,7 @@ static bool skip_otp;
+ 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 int ath10k_frame_mode = ATH10K_HW_TXRX_ETHERNET;
+ 
+ unsigned long ath10k_coredump_mask = BIT(ATH10K_FW_CRASH_DUMP_REGISTERS) |
+ 				     BIT(ATH10K_FW_CRASH_DUMP_CE_DATA);