blob: 51ffcfebb8711800b326cbe1bd822346bd277f55 [file] [log] [blame]
From e0fcc09873c502b3591934ad11d4382f78210b97 Mon Sep 17 00:00:00 2001
From: Peter Chiu <chui-hao.chiu@mediatek.com>
Date: Wed, 19 Apr 2023 18:32:41 +0800
Subject: [PATCH 2003/2020] mtk: wifi: mt76: add random early drop support
---
mt7996/debugfs.c | 1 +
mt7996/mac.c | 7 ++++
mt7996/mcu.c | 81 ++++++++++++++++++++++++++++++++++++++++++--
mt7996/mcu.h | 4 ++-
mt7996/mt7996.h | 5 ++-
mt7996/mtk_debugfs.c | 23 +++++++++++++
mt7996/mtk_mcu.c | 26 ++++++++++++++
mt7996/mtk_mcu.h | 24 +++++++++++++
8 files changed, 167 insertions(+), 4 deletions(-)
diff --git a/mt7996/debugfs.c b/mt7996/debugfs.c
index 67c6bd09..223b655e 100644
--- a/mt7996/debugfs.c
+++ b/mt7996/debugfs.c
@@ -621,6 +621,7 @@ mt7996_tx_stats_show(struct seq_file *file, void *data)
seq_printf(file, "Tx attempts: %8u (MPDUs)\n", attempts);
seq_printf(file, "Tx success: %8u (MPDUs)\n", success);
seq_printf(file, "Tx PER: %u%%\n", per);
+ seq_printf(file, "Tx RED drop: %8u\n", phy->red_drop);
mt7996_txbf_stat_read_phy(phy, file);
diff --git a/mt7996/mac.c b/mt7996/mac.c
index 408a59c5..a9d8f7dd 100644
--- a/mt7996/mac.c
+++ b/mt7996/mac.c
@@ -1176,6 +1176,13 @@ mt7996_mac_tx_free(struct mt7996_dev *dev, void *data, int len)
wcid->stats.tx_retries += tx_retries;
wcid->stats.tx_failed += tx_failed;
+
+ if (FIELD_GET(MT_TXFREE_INFO_STAT, info) == 2) {
+ struct mt7996_phy *mphy =
+ __mt7996_phy(dev, wcid->phy_idx);
+
+ mphy->red_drop++;
+ }
continue;
}
diff --git a/mt7996/mcu.c b/mt7996/mcu.c
index c980f345..e893e79b 100644
--- a/mt7996/mcu.c
+++ b/mt7996/mcu.c
@@ -3140,8 +3140,8 @@ int mt7996_mcu_init_firmware(struct mt7996_dev *dev)
if (ret)
return ret;
- return mt7996_mcu_wa_cmd(dev, MCU_WA_PARAM_CMD(SET),
- MCU_WA_PARAM_RED, 0, 0);
+ return mt7996_mcu_red_config(dev,
+ mtk_wed_device_active(&dev->mt76.mmio.wed));
}
int mt7996_mcu_init(struct mt7996_dev *dev)
@@ -3173,6 +3173,83 @@ out:
skb_queue_purge(&dev->mt76.mcu.res_q);
}
+static int mt7996_mcu_wa_red_config(struct mt7996_dev *dev)
+{
+#define RED_TOKEN_SRC_CNT 4
+#define RED_TOKEN_CONFIG 2
+ struct {
+ __le32 arg0;
+ __le32 arg1;
+ __le32 arg2;
+
+ u8 mode;
+ u8 version;
+ u8 _rsv[4];
+ __le16 len;
+
+ __le16 tcp_offset;
+ __le16 priority_offset;
+ __le16 token_per_src[RED_TOKEN_SRC_CNT];
+ __le16 token_thr_per_src[RED_TOKEN_SRC_CNT];
+
+ u8 _rsv2[604];
+ } __packed req = {
+ .arg0 = cpu_to_le32(MCU_WA_PARAM_RED_CONFIG),
+
+ .mode = RED_TOKEN_CONFIG,
+ .len = cpu_to_le16(sizeof(req) - sizeof(__le32) * 3),
+
+ .tcp_offset = cpu_to_le16(200),
+ .priority_offset = cpu_to_le16(255),
+ };
+ u8 i;
+
+ for (i = 0; i < RED_TOKEN_SRC_CNT; i++) {
+ req.token_per_src[i] = cpu_to_le16(MT7996_TOKEN_SIZE);
+ req.token_thr_per_src[i] = cpu_to_le16(MT7996_TOKEN_SIZE);
+ }
+
+ if (!mtk_wed_device_active(&dev->mt76.mmio.wed))
+ req.token_per_src[RED_TOKEN_SRC_CNT - 1] =
+ cpu_to_le16(MT7996_TOKEN_SIZE - MT7996_HW_TOKEN_SIZE);
+
+ return mt76_mcu_send_msg(&dev->mt76, MCU_WA_PARAM_CMD(SET),
+ &req, sizeof(req), false);
+}
+
+int mt7996_mcu_red_config(struct mt7996_dev *dev, bool enable)
+{
+#define RED_DISABLE 0
+#define RED_BY_WA_ENABLE 2
+ struct {
+ u8 __rsv1[4];
+
+ __le16 tag;
+ __le16 len;
+ u8 enable;
+ u8 __rsv2[3];
+ } __packed req = {
+ .tag = cpu_to_le16(UNI_VOW_RED_ENABLE),
+ .len = cpu_to_le16(sizeof(req) - 4),
+ .enable = enable ? RED_BY_WA_ENABLE : RED_DISABLE,
+ };
+ int ret;
+
+ ret = mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(VOW), &req,
+ sizeof(req), true);
+
+ if (ret)
+ return ret;
+
+ ret = mt7996_mcu_wa_cmd(dev, MCU_WA_PARAM_CMD(SET),
+ MCU_WA_PARAM_RED_EN, enable, 0);
+
+ if (ret || !enable)
+ return ret;
+
+ return mt7996_mcu_wa_red_config(dev);
+}
+
int mt7996_mcu_set_hdr_trans(struct mt7996_dev *dev, bool hdr_trans)
{
struct {
diff --git a/mt7996/mcu.h b/mt7996/mcu.h
index 398bf3d2..4fa399bc 100644
--- a/mt7996/mcu.h
+++ b/mt7996/mcu.h
@@ -346,8 +346,9 @@ enum {
enum {
MCU_WA_PARAM_PDMA_RX = 0x04,
MCU_WA_PARAM_CPU_UTIL = 0x0b,
- MCU_WA_PARAM_RED = 0x0e,
+ MCU_WA_PARAM_RED_EN = 0x0e,
MCU_WA_PARAM_HW_PATH_HIF_VER = 0x2f,
+ MCU_WA_PARAM_RED_CONFIG = 0x40,
};
enum mcu_mmps_mode {
@@ -919,6 +920,7 @@ enum {
UNI_VOW_DRR_CTRL,
UNI_VOW_RX_AT_AIRTIME_EN = 0x0b,
UNI_VOW_RX_AT_AIRTIME_CLR_EN = 0x0e,
+ UNI_VOW_RED_ENABLE = 0x18,
};
enum {
diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
index 9bcb6ff8..e6a0b15a 100644
--- a/mt7996/mt7996.h
+++ b/mt7996/mt7996.h
@@ -351,6 +351,7 @@ struct mt7996_phy {
bool has_aux_rx;
struct mt7996_scs_ctrl scs_ctrl;
+ u32 red_drop;
u8 muru_onoff;
@@ -696,6 +697,7 @@ int mt7996_mcu_rf_regval(struct mt7996_dev *dev, u32 regidx, u32 *val, bool set)
int mt7996_mcu_set_hdr_trans(struct mt7996_dev *dev, bool hdr_trans);
int mt7996_mcu_set_rro(struct mt7996_dev *dev, u16 tag, u16 val);
int mt7996_mcu_wa_cmd(struct mt7996_dev *dev, int cmd, u32 a1, u32 a2, u32 a3);
+int mt7996_mcu_red_config(struct mt7996_dev *dev, bool enable);
int mt7996_mcu_fw_log_2_host(struct mt7996_dev *dev, u8 type, u8 ctrl);
int mt7996_mcu_fw_dbg_ctrl(struct mt7996_dev *dev, u32 module, u8 level);
int mt7996_mcu_trigger_assert(struct mt7996_dev *dev);
@@ -869,11 +871,12 @@ void mt7996_mcu_set_ppdu_tx_type(struct mt7996_phy *phy, u8 ppdu_type);
void mt7996_mcu_set_nusers_ofdma(struct mt7996_phy *phy, u8 type, u8 ofdma_user_cnt);
void mt7996_mcu_set_cert(struct mt7996_phy *phy, u8 type);
void mt7996_tm_update_channel(struct mt7996_phy *phy);
+
+int mt7996_mcu_set_vow_drr_dbg(struct mt7996_dev *dev, u32 val);
#endif
#ifdef CONFIG_NET_MEDIATEK_SOC_WED
int mt7996_dma_rro_init(struct mt7996_dev *dev);
#endif /* CONFIG_NET_MEDIATEK_SOC_WED */
-
#endif
diff --git a/mt7996/mtk_debugfs.c b/mt7996/mtk_debugfs.c
index 0fdb911d..9cf3e6dc 100644
--- a/mt7996/mtk_debugfs.c
+++ b/mt7996/mtk_debugfs.c
@@ -2919,6 +2919,27 @@ static int mt7996_muru_prot_thr_set(void *data, u64 val)
DEFINE_DEBUGFS_ATTRIBUTE(fops_muru_prot_thr, NULL,
mt7996_muru_prot_thr_set, "%lld\n");
+static int
+mt7996_red_config_set(void *data, u64 val)
+{
+ struct mt7996_dev *dev = data;
+
+ return mt7996_mcu_red_config(dev, !!val);
+}
+
+DEFINE_DEBUGFS_ATTRIBUTE(fops_red_config, NULL,
+ mt7996_red_config_set, "%lld\n");
+
+static int
+mt7996_vow_drr_dbg(void *data, u64 val)
+{
+ struct mt7996_dev *dev = data;
+
+ return mt7996_mcu_set_vow_drr_dbg(dev, (u32)val);
+}
+DEFINE_DEBUGFS_ATTRIBUTE(fops_vow_drr_dbg, NULL,
+ mt7996_vow_drr_dbg, "%lld\n");
+
int mt7996_mtk_init_debugfs(struct mt7996_phy *phy, struct dentry *dir)
{
struct mt7996_dev *dev = phy->dev;
@@ -2995,6 +3016,8 @@ int mt7996_mtk_init_debugfs(struct mt7996_phy *phy, struct dentry *dir)
mt7996_wtbl_read);
debugfs_create_devm_seqfile(dev->mt76.dev, "token", dir, mt7996_token_read);
+ debugfs_create_file("red", 0200, dir, dev, &fops_red_config);
+ debugfs_create_file("vow_drr_dbg", 0200, dir, dev, &fops_vow_drr_dbg);
debugfs_create_u8("sku_disable", 0600, dir, &dev->dbg.sku_disable);
debugfs_create_file("scs_enable", 0200, dir, phy, &fops_scs_enable);
diff --git a/mt7996/mtk_mcu.c b/mt7996/mtk_mcu.c
index 2d8b08cd..6440efcf 100644
--- a/mt7996/mtk_mcu.c
+++ b/mt7996/mtk_mcu.c
@@ -1255,4 +1255,30 @@ void mt7996_mcu_set_cert(struct mt7996_phy *phy, u8 type)
sizeof(req), false);
}
+int mt7996_mcu_set_vow_drr_dbg(struct mt7996_dev *dev, u32 val)
+{
+#define MT7996_VOW_DEBUG_MODE 0xe
+ struct {
+ u8 __rsv1[4];
+
+ __le16 tag;
+ __le16 len;
+ u8 __rsv2[4];
+ __le32 action;
+ __le32 val;
+ u8 __rsv3[8];
+ } __packed req = {
+ .tag = cpu_to_le16(UNI_VOW_DRR_CTRL),
+ .len = cpu_to_le16(sizeof(req) - 4),
+ .action = cpu_to_le32(MT7996_VOW_DEBUG_MODE),
+ .val = cpu_to_le32(val),
+ };
+
+ if (val & ~VOW_DRR_DBG_FLAGS)
+ return -EINVAL;
+
+ return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(VOW), &req,
+ sizeof(req), true);
+}
+
#endif
diff --git a/mt7996/mtk_mcu.h b/mt7996/mtk_mcu.h
index 881afef1..7d76bfea 100644
--- a/mt7996/mtk_mcu.h
+++ b/mt7996/mtk_mcu.h
@@ -1022,6 +1022,30 @@ enum muru_vendor_ctrl {
MU_CTRL_DL_USER_CNT,
MU_CTRL_UL_USER_CNT,
};
+
+enum {
+ VOW_DRR_DBG_DUMP_BMP = BIT(0),
+ VOW_DRR_DBG_EST_AT_PRINT = BIT(1),
+ VOW_DRR_DBG_ADJ_GLOBAL_THLD = BIT(21),
+ VOW_DRR_DBG_PRN_LOUD = BIT(22),
+ VOW_DRR_DBG_PRN_ADJ_STA = BIT(23),
+ VOW_DRR_DBG_FIX_CR = GENMASK(27, 24),
+ VOW_DRR_DBG_CLR_FIX_CR = BIT(28),
+ VOW_DRR_DBG_DISABLE = BIT(29),
+ VOW_DRR_DBG_DUMP_CR = BIT(30),
+ VOW_DRR_DBG_PRN = BIT(31)
+};
+
+#define VOW_DRR_DBG_FLAGS (VOW_DRR_DBG_DUMP_BMP | \
+ VOW_DRR_DBG_EST_AT_PRINT | \
+ VOW_DRR_DBG_ADJ_GLOBAL_THLD | \
+ VOW_DRR_DBG_PRN_LOUD | \
+ VOW_DRR_DBG_PRN_ADJ_STA | \
+ VOW_DRR_DBG_FIX_CR | \
+ VOW_DRR_DBG_CLR_FIX_CR | \
+ VOW_DRR_DBG_DISABLE | \
+ VOW_DRR_DBG_DUMP_CR | \
+ VOW_DRR_DBG_PRN)
#endif
#endif
--
2.18.0