<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">From 3ba3a54fce8cc3165c41e01bda6c3d2cc9a570f9 Mon Sep 17 00:00:00 2001
From: Peter Chiu &lt;chui-hao.chiu@mediatek.com&gt;
Date: Wed, 19 Apr 2023 18:32:41 +0800
Subject: [PATCH 2008/2010] wifi: mt76: add random early drop support

---
 mt7996/mcu.c    | 77 +++++++++++++++++++++++++++++++++++++++++++++++--
 mt7996/mcu.h    |  4 ++-
 mt7996/mt7996.h |  1 +
 3 files changed, 79 insertions(+), 3 deletions(-)

diff --git a/mt7996/mcu.c b/mt7996/mcu.c
index 42cd1d2..4c7cc09 100644
--- a/mt7996/mcu.c
+++ b/mt7996/mcu.c
@@ -2930,8 +2930,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(&amp;dev-&gt;mt76.mmio.wed));
 }
 
 int mt7996_mcu_init(struct mt7996_dev *dev)
@@ -2963,6 +2963,79 @@ out:
 	skb_queue_purge(&amp;dev-&gt;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 &lt; 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);
+	}
+
+	return mt76_mcu_send_msg(&amp;dev-&gt;mt76, MCU_WA_PARAM_CMD(SET),
+				 &amp;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(&amp;dev-&gt;mt76, MCU_WM_UNI_CMD(VOW), &amp;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 a0cbf92..ec074bc 100644
--- a/mt7996/mcu.h
+++ b/mt7996/mcu.h
@@ -239,8 +239,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 {
@@ -695,6 +696,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 23d4744..3463eb9 100644
--- a/mt7996/mt7996.h
+++ b/mt7996/mt7996.h
@@ -717,6 +717,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, u8 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);
-- 
2.18.0

</pre></body></html>