wlan-ap-Telecominfraproject/feeds/wifi-ax/mac80211/patches/qca/211-ath11k-custom-aggregation-size-support-over-WMI.patch
John Crispin 8cd26b4b50 ipq807x: update to 11.4-CS
Signed-off-by: John Crispin <john@phrozen.org>
2021-09-14 09:16:23 +02:00

272 lines
8.9 KiB
Diff

From 815ddd8110e03496192c171f3058f85096fb2049 Mon Sep 17 00:00:00 2001
From: Ramya Gnanasekar <rgnanase@codeaurora.org>
Date: Wed, 7 Oct 2020 20:08:49 +0530
Subject: [PATCH] ath11k: custom aggregation size support over WMI
This patch is to support custom aggregation size config for A-MPDU
and A-MSDU through WMI command per vdev_id. rx_aggr_size_disable is
set true to avoid fw from considering rx_aggr_size paramater.
AC is set to all by default. Upon configuring 0, firmware will default
AMPDU aggregation size to 1 and AMDSU to 7.
Default aggregation limit is:
* AMPDU : 0 - 255
* AMSDU : 0 - 7
echo 64 > /sys/kernel/debug/ieee80211/phy0/netdev:wlan0/ampdu_aggr_size
echo 6 > /sys/kernel/debug/ieee80211/phy0/netdev:wlan0/amsdu_aggr_size
Signed-off-by: Ramya Gnanasekar <rgnanase@codeaurora.org>
---
drivers/net/wireless/ath/ath11k/debugfs.c | 86 +++++++++++++++++++++++++++++++++
drivers/net/wireless/ath/ath11k/debugfs.h | 2 +
drivers/net/wireless/ath/ath11k/mac.c | 2 +
drivers/net/wireless/ath/ath11k/wmi.c | 54 +++++++++++++++++++++
drivers/net/wireless/ath/ath11k/wmi.h | 52 ++++++++++++++++++++
5 files changed, 196 insertions(+)
--- a/drivers/net/wireless/ath/ath11k/debugfs.c
+++ b/drivers/net/wireless/ath/ath11k/debugfs.c
@@ -250,6 +250,92 @@ void ath11k_debugfs_twt(struct ath11k_vi
}
#endif
+static ssize_t ath11k_write_ampdu_aggr_size(struct file *file,
+ const char __user *ubuf,
+ size_t count, loff_t *ppos)
+{
+ struct ath11k_vif *arvif = file->private_data;
+ struct ath11k_base *ab = arvif->ar->ab;
+ unsigned int tx_aggr_size = 0;
+ int ret;
+ struct set_custom_aggr_size_params params = {0};
+
+ if (kstrtouint_from_user(ubuf, count, 0, &tx_aggr_size))
+ return -EINVAL;
+
+ if (tx_aggr_size > ATH11K_CONFIG_AGGR_MAX_AMPDU_SIZE) {
+ ath11k_warn(ab, "Valid AMPDU Aggregation Size is in the range 0-255");
+ return -EINVAL;
+ }
+
+ params.aggr_type = WMI_VDEV_CUSTOM_AGGR_TYPE_AMPDU;
+ params.tx_aggr_size = tx_aggr_size;
+ params.rx_aggr_size_disable = true;
+ params.vdev_id = arvif->vdev_id;
+
+ ret = ath11k_wmi_send_aggr_size_cmd(arvif->ar, &params);
+ if (ret)
+ ath11k_warn(ab, "Failed to set ampdu config vdev_id %d"
+ "ret %d \n",params.vdev_id, ret);
+
+ return ret ? ret : count;
+}
+
+static const struct file_operations fops_ampdu_aggr_size = {
+ .write = ath11k_write_ampdu_aggr_size,
+ .open = simple_open,
+ .owner = THIS_MODULE,
+ .llseek = default_llseek,
+};
+
+static ssize_t ath11k_write_amsdu_aggr_size(struct file *file,
+ const char __user *ubuf,
+ size_t count, loff_t *ppos)
+{
+ struct ath11k_vif *arvif = file->private_data;
+ struct ath11k_base *ab = arvif->ar->ab;
+ unsigned int tx_aggr_size = 0;
+ int ret;
+ struct set_custom_aggr_size_params params = {0};
+
+ if (kstrtouint_from_user(ubuf, count, 0, &tx_aggr_size))
+ return -EINVAL;
+
+ if (tx_aggr_size > ATH11K_CONFIG_AGGR_MAX_AMSDU_SIZE) {
+ ath11k_warn(ab, "Valid AMSDU Aggregation size is in the range 0-7");
+ return -EINVAL;
+ }
+
+ params.aggr_type = WMI_VDEV_CUSTOM_AGGR_TYPE_AMSDU;
+ params.tx_aggr_size = tx_aggr_size;
+ params.rx_aggr_size_disable = true;
+ params.vdev_id = arvif->vdev_id;
+
+ ret = ath11k_wmi_send_aggr_size_cmd(arvif->ar, &params);
+ if (ret)
+ ath11k_warn(ab, "Failed to set amsdu config vdev_id %d"
+ "ret %d \n",params.vdev_id, ret);
+
+ return ret ? ret : count;
+}
+
+static const struct file_operations fops_amsdu_aggr_size = {
+ .write = ath11k_write_amsdu_aggr_size,
+ .open = simple_open,
+ .owner = THIS_MODULE,
+ .llseek = default_llseek,
+};
+
+void ath11k_debug_aggr_size_config_init(struct ath11k_vif *arvif)
+{
+ debugfs_create_file("ampdu_aggr_size", 0644,
+ arvif->vif->debugfs_dir, arvif,
+ &fops_ampdu_aggr_size);
+ debugfs_create_file("amsdu_aggr_size", 0644,
+ arvif->vif->debugfs_dir, arvif,
+ &fops_amsdu_aggr_size);
+}
+
static void ath11k_fw_stats_pdevs_free(struct list_head *head)
{
struct ath11k_fw_stats_pdev *i, *tmp;
--- a/drivers/net/wireless/ath/ath11k/debugfs.h
+++ b/drivers/net/wireless/ath/ath11k/debugfs.h
@@ -155,6 +155,8 @@ static inline void ath11k_debugfs_twt(st
}
#endif
+void ath11k_debug_aggr_size_config_init(struct ath11k_vif *arvif);
+
#ifdef CPTCFG_ATH11K_DEBUGFS
int ath11k_debugfs_create(void);
void ath11k_debugfs_destroy(void);
--- a/drivers/net/wireless/ath/ath11k/mac.c
+++ b/drivers/net/wireless/ath/ath11k/mac.c
@@ -5987,6 +5987,8 @@ static int ath11k_mac_op_add_interface(s
goto err_peer_del;
}
+ ath11k_debug_aggr_size_config_init(arvif);
+
mutex_unlock(&ar->conf_mutex);
return ret;
--- a/drivers/net/wireless/ath/ath11k/wmi.c
+++ b/drivers/net/wireless/ath/ath11k/wmi.c
@@ -3791,6 +3791,58 @@ int ath11k_wmi_send_bss_color_change_ena
return ret;
}
+int ath11k_wmi_send_aggr_size_cmd(struct ath11k *ar,
+ struct set_custom_aggr_size_params *params)
+{
+ struct ath11k_pdev_wmi *wmi = ar->wmi;
+ struct ath11k_base *ab = wmi->wmi_ab->ab;
+ struct wmi_set_custom_aggr_size_params_cmd *cmd = NULL;
+ struct sk_buff *skb;
+ int ret, len;
+
+ len = sizeof(*cmd);
+
+ skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len);
+ if (!skb)
+ return -ENOMEM;
+
+ cmd = (void *)skb->data;
+ cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG,
+ WMI_TAG_VDEV_SET_CUSTOM_AGGR_SIZE_CMD) |
+ FIELD_PREP(WMI_TLV_LEN, len - TLV_HDR_SIZE);
+
+ cmd->vdev_id = params->vdev_id;
+ cmd->tx_aggr_size = params->tx_aggr_size;
+ cmd->rx_aggr_size = params->rx_aggr_size;
+ cmd->enable_bitmap = FIELD_PREP(WMI_VDEV_AGGR_AC, params->ac) |
+ FIELD_PREP(WMI_VDEV_AGGR_TYPE, params->aggr_type) |
+ FIELD_PREP(WMI_VDEV_TX_AGGR_SZ_DISABLE,
+ params->tx_aggr_size_disable) |
+ FIELD_PREP(WMI_VDEV_RX_AGGR_SZ_DISABLE,
+ params->rx_aggr_size_disable) |
+ FIELD_PREP(WMI_VDEV_AGGR_AC_ENABLE,
+ params->tx_ac_enable);
+
+ ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
+ "WMI set aggr size vdev_id %d tx aggr size %d rx_aggr_size %d "
+ "access category %d aggr type %d tx_aggr_size_disable %d "
+ "rx_aggr_size_disable %d tx_ac_enable %d ", params->vdev_id,
+ params->tx_aggr_size, params->rx_aggr_size, params->ac,
+ params->aggr_type, params->tx_aggr_size_disable,
+ params->rx_aggr_size_disable, params->tx_ac_enable);
+
+ ret = ath11k_wmi_cmd_send(wmi, skb,
+ WMI_VDEV_SET_CUSTOM_AGGR_SIZE_CMDID);
+
+ if (ret) {
+ ath11k_warn(ab,
+ "Failed to send WMI_VDEV_SET_CUSTOM_AGGR_SIZE_CMDID");
+ dev_kfree_skb(skb);
+ }
+
+ return ret;
+}
+
int ath11k_wmi_fils_discovery_tmpl(struct ath11k *ar, u32 vdev_id,
struct sk_buff *tmpl)
{
--- a/drivers/net/wireless/ath/ath11k/wmi.h
+++ b/drivers/net/wireless/ath/ath11k/wmi.h
@@ -5244,6 +5244,56 @@ struct wmi_pdev_obss_pd_bitmap_cmd {
u32 bitmap[2];
} __packed;
+#define WMI_VDEV_AGGR_AC GENMASK(2, 0)
+#define WMI_VDEV_AGGR_TYPE GENMASK(3, 2)
+#define WMI_VDEV_TX_AGGR_SZ_DISABLE GENMASK(4, 3)
+#define WMI_VDEV_RX_AGGR_SZ_DISABLE GENMASK(5, 4)
+#define WMI_VDEV_AGGR_AC_ENABLE GENMASK(6, 5)
+
+struct set_custom_aggr_size_params {
+ u32 vdev_id;
+ u32 tx_aggr_size;
+ u32 rx_aggr_size;
+ u32 ac;
+ u32 aggr_type;
+ u32 tx_aggr_size_disable;
+ u32 rx_aggr_size_disable;
+ u32 tx_ac_enable;
+};
+
+struct wmi_set_custom_aggr_size_params_cmd {
+ u32 tlv_header; /* TLV tag and len */
+ u32 vdev_id; /* vdev id indicating to which aggregation size will be applied. */
+ /* Size for tx aggregation for the vdev mentioned in vdev id
+ * (max MPDUs per A-MPDU or max MSDUs per A-MSDU based on aggr_type field)
+ */
+ u32 tx_aggr_size;
+
+ u32 rx_aggr_size; /* Size for rx aggregation (block ack window size limit)for vdev id */
+
+ /* To set TX aggregation size limits per VDEV per AC
+ * bits 1:0 (ac):
+ * Access Category (0x0=BE, 0x1=BK, 0x2=VI, 0x3=VO)
+ * If tx_ac_enable bit is not set, tx_aggr_size is applied
+ * for all Access Categories
+ * bit 2 (aggr_type): TX Aggregation Type (0=A-MPDU, 1=A-MSDU)
+ * bit 3 (tx_aggr_size_disable): If set tx_aggr_size is invalid
+ * bit 4 (rx_aggr_size_disable): If set rx_aggr_size is invalid
+ * bit 5 (tx_ac_enable): If set, above ac bitmap is valid.
+ * bits 31:6: Reserved bits. should be set to zero.
+ */
+ u32 enable_bitmap;
+} __packed;
+
+enum wmi_vdev_aggr_type {
+ WMI_VDEV_CUSTOM_AGGR_TYPE_AMPDU = 0,
+ WMI_VDEV_CUSTOM_AGGR_TYPE_AMSDU = 1,
+ WMI_VDEV_CUSTOM_AGGR_TYPE_MAX,
+};
+
+#define ATH11K_CONFIG_AGGR_MAX_AMPDU_SIZE 255 /* Maximum Frames for Custom AMPDU Size */
+#define ATH11K_CONFIG_AGGR_MAX_AMSDU_SIZE 7 /* Maximum Frames for Custom AMSDU Size */
+
#define ATH11K_BSS_COLOR_COLLISION_SCAN_PERIOD_MS 200
#define ATH11K_OBSS_COLOR_COLLISION_DETECTION_DISABLE 0
#define ATH11K_OBSS_COLOR_COLLISION_DETECTION 1
@@ -6007,5 +6057,7 @@ int ath11k_wmi_wow_enable(struct ath11k
int ath11k_wmi_pdev_m3_dump_enable(struct ath11k *ar, u32 enable);
int ath11k_wmi_pdev_get_tpc_table_cmdid(struct ath11k *ar);
void ath11k_wmi_free_tpc_stats_mem(struct ath11k *ar);
+int ath11k_wmi_send_aggr_size_cmd(struct ath11k *ar,
+ struct set_custom_aggr_size_params *params);
#endif