From 08e27a0c0cecfe9e07bc03e78ae9d59201194534 Mon Sep 17 00:00:00 2001
From: Stijn Segers <foss@volatilesystems.org>
Date: Wed, 16 Jun 2021 20:17:10 +0200
Subject: [PATCH] mt76: mt7615: clear pending packets in hardware

Affects MT7613BE (see GitHub issue 518). Adds the following hack:

https://github.com/ptpt52/mt76/commit/eceab757eb708a8348e0b8d6fa860b26eec5e807

Modified to follow upstream mt76 commit a27dfcb6 from 2021-06-10,
without it mt76 2021-07-14 and higher would break as documented on the
OpenWrt forums:

https://forum.openwrt.org/t/adding-openwrt-support-for-archer-a6-v3/77607/279

Signed-off-by: Stijn Segers <foss@volatilesystems.org>
---
 package/kernel/mt76/Makefile                  |  2 +-
 ...15-hack-to-clear-all-pending-packets.patch | 54 +++++++++++++++++++
 2 files changed, 55 insertions(+), 1 deletion(-)
 create mode 100644 package/kernel/mt76/patches/001-mt7615-hack-to-clear-all-pending-packets.patch

diff --git a/package/kernel/mt76/Makefile b/package/kernel/mt76/Makefile
index 431c57a240..bda23ceb8b 100644
--- a/package/kernel/mt76/Makefile
+++ b/package/kernel/mt76/Makefile
@@ -1,7 +1,7 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=mt76
-PKG_RELEASE=4
+PKG_RELEASE=5
 
 PKG_LICENSE:=GPLv2
 PKG_LICENSE_FILES:=
diff --git a/package/kernel/mt76/patches/001-mt7615-hack-to-clear-all-pending-packets.patch b/package/kernel/mt76/patches/001-mt7615-hack-to-clear-all-pending-packets.patch
new file mode 100644
index 0000000000..1fa0120dbb
--- /dev/null
+++ b/package/kernel/mt76/patches/001-mt7615-hack-to-clear-all-pending-packets.patch
@@ -0,0 +1,54 @@
+From eceab757eb708a8348e0b8d6fa860b26eec5e807 Mon Sep 17 00:00:00 2001
+From: Chen Minqiang <ptpt52@gmail.com>
+Date: Tue, 20 Apr 2021 11:46:21 +0800
+Subject: [PATCH] mt7615: hack to clear all pending packets
+
+See MT76 bug #518: https://github.com/openwrt/mt76/issues/518
+
+[Adapted __mt7615_mcu_add_sta after upstream mt76 commit a27dfcb6]
+
+---
+ mt7615/mcu.c | 16 ++++++++++++++++
+ 1 file changed, 16 insertions(+)
+
+diff --git a/mt7615/mcu.c b/mt7615/mcu.c
+index 856ff36e..2c67abb6 100644
+--- a/mt7615/mcu.c
++++ b/mt7615/mcu.c
+@@ -750,6 +750,11 @@ mt7615_mcu_add_dev(struct mt7615_phy *phy, struct ieee80211_vif *vif,
+ 				 &data, sizeof(data), true);
+ }
+ 
++static int
++__mt7615_mcu_add_sta(struct mt76_phy *phy, struct ieee80211_vif *vif,
++		     struct ieee80211_sta *sta, bool enable, int cmd,
++		     bool offload_fw);
++
+ static int
+ mt7615_mcu_add_beacon_offload(struct mt7615_dev *dev,
+ 			      struct ieee80211_hw *hw,
+@@ -815,6 +819,11 @@ mt7615_mcu_add_beacon_offload(struct mt7615_dev *dev,
+ 	}
+ 	dev_kfree_skb(skb);
+ 
++	if (is_mt7663(&dev->mt76)) {
++		//hack to clear all pending packets
++		__mt7615_mcu_add_sta(dev->phy.mt76, vif, NULL, false, MCU_EXT_CMD_STA_REC_UPDATE, false);
++		__mt7615_mcu_add_sta(dev->phy.mt76, vif, NULL, true, MCU_EXT_CMD_STA_REC_UPDATE, false);
++	}
+ out:
+ 	return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_BCN_OFFLOAD, &req,
+ 				 sizeof(req), true);
+@@ -1191,6 +1200,12 @@ static int
+ mt7615_mcu_add_sta(struct mt7615_phy *phy, struct ieee80211_vif *vif,
+ 		   struct ieee80211_sta *sta, bool enable)
+ {
++	if (is_mt7663(&phy->dev->mt76) && !enable) {
++		//hack to clear all pending packets
++		__mt7615_mcu_add_sta(phy->mt76, vif, sta, enable, MCU_EXT_CMD_STA_REC_UPDATE, false);
++		__mt7615_mcu_add_sta(phy->mt76, vif, NULL, false, MCU_EXT_CMD_STA_REC_UPDATE, false);
++		__mt7615_mcu_add_sta(phy->mt76, vif, NULL, true, MCU_EXT_CMD_STA_REC_UPDATE, false);
++	}
+ 	return __mt7615_mcu_add_sta(phy->mt76, vif, sta, enable,
+ 				    MCU_EXT_CMD_STA_REC_UPDATE);
+ }
-- 
2.30.2

