[][MAC80211][wifi6][mt76][Add per-band token limits and debugfs]

[Description]
Add a threshold for per-band token count.
  The band0/1 use the same token pool so a band cannot transmit if
  the other band occupy too many tokens. With this patch, we can
  prevent a band from interfering with the other band.
Add debugfs knob to show per band token count

[Release-log]
N/A

Change-Id: Iffe02b57e4f9110cf964230c3cba736ad36d2c02
Reviewed-on: https://gerrit.mediatek.inc/c/openwrt/feeds/mtk_openwrt_feeds/+/8668370
diff --git a/autobuild_mac80211_release/package/kernel/mt76/patches/0015-wifi-mt76-mt7915-limit-per-band-token-count.patch b/autobuild_mac80211_release/package/kernel/mt76/patches/0015-wifi-mt76-mt7915-limit-per-band-token-count.patch
new file mode 100644
index 0000000..c9e0b05
--- /dev/null
+++ b/autobuild_mac80211_release/package/kernel/mt76/patches/0015-wifi-mt76-mt7915-limit-per-band-token-count.patch
@@ -0,0 +1,228 @@
+From 47ea10a75083acf3af7826124ef0166f2debc5c0 Mon Sep 17 00:00:00 2001
+From: Peter Chiu <chui-hao.chiu@mediatek.com>
+Date: Mon, 29 Jan 2024 15:33:24 +0800
+Subject: [PATCH 15/15] wifi: mt76: mt7915: limit per-band token count
+
+Add a threshold for per-band token count to prevent a band from interfering
+with the other band.
+
+Signed-off-by: Peter Chiu <chui-hao.chiu@mediatek.com>
+---
+ mt76.h           |  8 +++++++-
+ mt7915/init.c    |  3 +++
+ mt7915/mac.c     |  3 ++-
+ mt7921/pci_mac.c |  2 +-
+ mt7925/pci_mac.c |  2 +-
+ mt7996/init.c    |  5 +++++
+ mt7996/mac.c     |  3 ++-
+ tx.c             | 20 ++++++++++++++++++--
+ 8 files changed, 39 insertions(+), 7 deletions(-)
+
+diff --git a/mt76.h b/mt76.h
+index 03116ffe..b1f49973 100644
+--- a/mt76.h
++++ b/mt76.h
+@@ -402,6 +402,8 @@ struct mt76_txwi_cache {
+ 	struct list_head list;
+ 	dma_addr_t dma_addr;
+ 
++	u8 phy_idx;
++
+ 	union {
+ 		struct sk_buff *skb;
+ 		void *ptr;
+@@ -814,6 +816,7 @@ struct mt76_phy {
+ 		bool al;
+ 		u8 pin;
+ 	} leds;
++	int tokens;
+ };
+ 
+ struct mt76_dev {
+@@ -867,6 +870,8 @@ struct mt76_dev {
+ 	u16 wed_token_count;
+ 	u16 token_count;
+ 	u16 token_size;
++	u16 token_threshold;
++	u8 num_phy;
+ 
+ 	spinlock_t rx_token_lock;
+ 	struct idr rx_token;
+@@ -1657,7 +1662,8 @@ static inline bool mt76_queue_is_wed_rx(struct mt76_queue *q)
+ 
+ struct mt76_txwi_cache *
+ mt76_token_release(struct mt76_dev *dev, int token, bool *wake);
+-int mt76_token_consume(struct mt76_dev *dev, struct mt76_txwi_cache **ptxwi);
++int mt76_token_consume(struct mt76_dev *dev, struct mt76_txwi_cache **ptxwi,
++		       u8 phy_idx);
+ void __mt76_set_tx_blocked(struct mt76_dev *dev, bool blocked);
+ struct mt76_txwi_cache *mt76_rx_token_release(struct mt76_dev *dev, int token);
+ int mt76_rx_token_consume(struct mt76_dev *dev, void *ptr,
+diff --git a/mt7915/init.c b/mt7915/init.c
+index 2fc1f3ce..6ba98433 100644
+--- a/mt7915/init.c
++++ b/mt7915/init.c
+@@ -1221,6 +1221,8 @@ int mt7915_register_device(struct mt7915_dev *dev)
+ 
+ 	dev->dbdc_support = mt7915_band_config(dev);
+ 
++	dev->mt76.num_phy = 1 + !!dev->dbdc_support;
++
+ 	phy2 = mt7915_alloc_ext_phy(dev);
+ 	if (IS_ERR(phy2))
+ 		return PTR_ERR(phy2);
+@@ -1253,6 +1255,7 @@ int mt7915_register_device(struct mt7915_dev *dev)
+ 	}
+ 
+ 	dev->recovery.hw_init_done = true;
++	dev->mt76.token_threshold = dev->mt76.token_size / dev->mt76.num_phy;
+ 
+ 	ret = mt7915_init_debugfs(&dev->phy);
+ 	if (ret)
+diff --git a/mt7915/mac.c b/mt7915/mac.c
+index faa5ed36..8e98e5ae 100644
+--- a/mt7915/mac.c
++++ b/mt7915/mac.c
+@@ -738,6 +738,7 @@ int mt7915_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
+ 	struct mt76_connac_fw_txp *txp;
+ 	struct mt76_txwi_cache *t;
+ 	int id, i, nbuf = tx_info->nbuf - 1;
++	u8 phy_idx = (info->hw_queue & MT_TX_HW_QUEUE_PHY) >> 2;
+ 	u8 *txwi = (u8 *)txwi_ptr;
+ 	int pid;
+ 
+@@ -761,7 +762,7 @@ int mt7915_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
+ 	t = (struct mt76_txwi_cache *)(txwi + mdev->drv->txwi_size);
+ 	t->skb = tx_info->skb;
+ 
+-	id = mt76_token_consume(mdev, &t);
++	id = mt76_token_consume(mdev, &t, phy_idx);
+ 	if (id < 0)
+ 		return id;
+ 
+diff --git a/mt7921/pci_mac.c b/mt7921/pci_mac.c
+index c866144f..3282507a 100644
+--- a/mt7921/pci_mac.c
++++ b/mt7921/pci_mac.c
+@@ -27,7 +27,7 @@ int mt7921e_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
+ 	t = (struct mt76_txwi_cache *)(txwi + mdev->drv->txwi_size);
+ 	t->skb = tx_info->skb;
+ 
+-	id = mt76_token_consume(mdev, &t);
++	id = mt76_token_consume(mdev, &t, 0);
+ 	if (id < 0)
+ 		return id;
+ 
+diff --git a/mt7925/pci_mac.c b/mt7925/pci_mac.c
+index 9fca8879..f1d615c0 100644
+--- a/mt7925/pci_mac.c
++++ b/mt7925/pci_mac.c
+@@ -27,7 +27,7 @@ int mt7925e_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
+ 	t = (struct mt76_txwi_cache *)(txwi + mdev->drv->txwi_size);
+ 	t->skb = tx_info->skb;
+ 
+-	id = mt76_token_consume(mdev, &t);
++	id = mt76_token_consume(mdev, &t, 0);
+ 	if (id < 0)
+ 		return id;
+ 
+diff --git a/mt7996/init.c b/mt7996/init.c
+index 9aa97e4a..7549a108 100644
+--- a/mt7996/init.c
++++ b/mt7996/init.c
+@@ -634,6 +634,8 @@ static int mt7996_register_phy(struct mt7996_dev *dev, struct mt7996_phy *phy,
+ 		mtk_wed_device_start(&dev->mt76.mmio.wed_hif2, irq_mask);
+ 	}
+ 
++	dev->mt76.num_phy++;
++
+ 	return 0;
+ 
+ error:
+@@ -1330,6 +1332,8 @@ int mt7996_register_device(struct mt7996_dev *dev)
+ 	if (ret)
+ 		return ret;
+ 
++	dev->mt76.num_phy = 1;
++
+ 	ret = mt7996_register_phy(dev, mt7996_phy2(dev), MT_BAND1);
+ 	if (ret)
+ 		return ret;
+@@ -1342,6 +1346,7 @@ int mt7996_register_device(struct mt7996_dev *dev)
+ 
+ 	dev->recovery.hw_init_done = true;
+ 
++	dev->mt76.token_threshold = dev->mt76.token_size / dev->mt76.num_phy;
+ 	ret = mt7996_init_debugfs(&dev->phy);
+ 	if (ret)
+ 		goto error;
+diff --git a/mt7996/mac.c b/mt7996/mac.c
+index 0384fb05..feb5299d 100644
+--- a/mt7996/mac.c
++++ b/mt7996/mac.c
+@@ -922,6 +922,7 @@ int mt7996_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
+ 	struct mt76_txwi_cache *t;
+ 	int id, i, pid, nbuf = tx_info->nbuf - 1;
+ 	bool is_8023 = info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP;
++	u8 phy_idx = (info->hw_queue & MT_TX_HW_QUEUE_PHY) >> 2;
+ 	u8 *txwi = (u8 *)txwi_ptr;
+ 
+ 	if (unlikely(tx_info->skb->len <= ETH_HLEN))
+@@ -933,7 +934,7 @@ int mt7996_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
+ 	t = (struct mt76_txwi_cache *)(txwi + mdev->drv->txwi_size);
+ 	t->skb = tx_info->skb;
+ 
+-	id = mt76_token_consume(mdev, &t);
++	id = mt76_token_consume(mdev, &t, phy_idx);
+ 	if (id < 0)
+ 		return id;
+ 
+diff --git a/tx.c b/tx.c
+index 4596b367..b602d9d7 100644
+--- a/tx.c
++++ b/tx.c
+@@ -825,16 +825,30 @@ void __mt76_set_tx_blocked(struct mt76_dev *dev, bool blocked)
+ }
+ EXPORT_SYMBOL_GPL(__mt76_set_tx_blocked);
+ 
+-int mt76_token_consume(struct mt76_dev *dev, struct mt76_txwi_cache **ptxwi)
++int mt76_token_consume(struct mt76_dev *dev, struct mt76_txwi_cache **ptxwi,
++		       u8 phy_idx)
+ {
++	struct mt76_phy *phy = phy_idx < __MT_MAX_BAND ? dev->phys[phy_idx] : NULL;
+ 	int token;
+ 
+ 	spin_lock_bh(&dev->token_lock);
+ 
++	if (dev->num_phy > 1 && phy && phy->tokens > dev->token_threshold) {
++		spin_unlock_bh(&dev->token_lock);
++
++		return -EINVAL;
++	}
++
+ 	token = idr_alloc(&dev->token, *ptxwi, 0, dev->token_size, GFP_ATOMIC);
+-	if (token >= 0)
++	if (token >= 0) {
+ 		dev->token_count++;
+ 
++		if (dev->num_phy > 1 && phy) {
++			(*ptxwi)->phy_idx = phy_idx;
++			phy->tokens++;
++		}
++	}
++
+ #ifdef CONFIG_NET_MEDIATEK_SOC_WED
+ 	if (mtk_wed_device_active(&dev->mmio.wed) &&
+ 	    token >= dev->mmio.wed.wlan.token_start)
+@@ -878,6 +892,8 @@ mt76_token_release(struct mt76_dev *dev, int token, bool *wake)
+ 	txwi = idr_remove(&dev->token, token);
+ 	if (txwi) {
+ 		dev->token_count--;
++		if (dev->num_phy > 1 && dev->phys[txwi->phy_idx])
++			dev->phys[txwi->phy_idx]->tokens--;
+ 
+ #ifdef CONFIG_NET_MEDIATEK_SOC_WED
+ 		if (mtk_wed_device_active(&dev->mmio.wed) &&
+-- 
+2.18.0
+
diff --git a/autobuild_mac80211_release/package/kernel/mt76/patches/1038-wifi-mt76-update-debugfs-knob-for-tx-tokens.patch b/autobuild_mac80211_release/package/kernel/mt76/patches/1038-wifi-mt76-update-debugfs-knob-for-tx-tokens.patch
new file mode 100644
index 0000000..1bff9a7
--- /dev/null
+++ b/autobuild_mac80211_release/package/kernel/mt76/patches/1038-wifi-mt76-update-debugfs-knob-for-tx-tokens.patch
@@ -0,0 +1,84 @@
+From ea03566cfd54a952576c0f21e157854803e04963 Mon Sep 17 00:00:00 2001
+From: Evelyn Tsai <evelyn.tsai@mediatek.com>
+Date: Thu, 24 Aug 2023 03:01:27 +0800
+Subject: [PATCH 1038/1049] wifi: mt76: update debugfs knob for tx tokens
+
+1. dump token pending time
+2. dump per-band token counts
+
+Signed-off-by: Peter Chiu <chui-hao.chiu@mediatek.com>
+---
+ mt76.h               |  1 +
+ mt7915/mac.c         |  2 ++
+ mt7915/mtk_debugfs.c | 24 +++++++++++++++++++-----
+ 3 files changed, 22 insertions(+), 5 deletions(-)
+
+diff --git a/mt76.h b/mt76.h
+index 051afa76..d7eb6c8f 100644
+--- a/mt76.h
++++ b/mt76.h
+@@ -403,6 +403,7 @@ struct mt76_txwi_cache {
+ 	dma_addr_t dma_addr;
+ 
+ 	u8 phy_idx;
++	unsigned long jiffies;
+ 
+ 	union {
+ 		struct sk_buff *skb;
+diff --git a/mt7915/mac.c b/mt7915/mac.c
+index 7f4778f0..763e1fb3 100644
+--- a/mt7915/mac.c
++++ b/mt7915/mac.c
+@@ -811,6 +811,8 @@ int mt7915_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
+ 	if (id < 0)
+ 		return id;
+ 
++	t->jiffies = jiffies;
++
+ 	pid = mt76_tx_status_skb_add(mdev, wcid, tx_info->skb);
+ 	mt7915_mac_write_txwi(mdev, txwi_ptr, tx_info->skb, wcid, pid, key,
+ 			      qid, 0);
+diff --git a/mt7915/mtk_debugfs.c b/mt7915/mtk_debugfs.c
+index 56b9e85e..6db22704 100644
+--- a/mt7915/mtk_debugfs.c
++++ b/mt7915/mtk_debugfs.c
+@@ -2203,17 +2203,31 @@ static int mt7915_mibinfo_band1(struct seq_file *s, void *data)
+ static int mt7915_token_read(struct seq_file *s, void *data)
+ {
+ 	struct mt7915_dev *dev = dev_get_drvdata(s->private);
+-	int id, count = 0;
++	struct mt76_dev *mdev = &dev->mt76;
++	int id, i;
+ 	struct mt76_txwi_cache *txwi;
+ 
+ 	seq_printf(s, "Cut through token:\n");
+ 	spin_lock_bh(&dev->mt76.token_lock);
+ 	idr_for_each_entry(&dev->mt76.token, txwi, id) {
+-		seq_printf(s, "%4d ", id);
+-		count++;
+-		if (count % 8 == 0)
+-			seq_printf(s, "\n");
++		seq_printf(s, "%4d (token pending %u ms)\n", id,
++			   jiffies_to_msecs(jiffies - txwi->jiffies));
++	}
++
++	if (!dev->dbdc_support)
++		goto out;
++
++	for (i = 0; i < MT_BAND2; i++) {
++		struct mt76_phy *mphy = mdev->phys[i];
++
++		if (!mphy)
++			continue;
++
++		seq_printf(s, "Band%d consume: %d, free:%d total: %d\n",
++			   i, mphy->tokens, mdev->token_threshold - mphy->tokens,
++			   mdev->token_threshold);
+ 	}
++out:
+ 	spin_unlock_bh(&dev->mt76.token_lock);
+ 	seq_printf(s, "\n");
+ 
+-- 
+2.18.0
+
diff --git a/autobuild_mac80211_release/package/kernel/mt76/patches/1038-wifi-mt76-update-debugfs-knob-to-dump-token-pending-.patch b/autobuild_mac80211_release/package/kernel/mt76/patches/1038-wifi-mt76-update-debugfs-knob-to-dump-token-pending-.patch
deleted file mode 100644
index 7586a2a..0000000
--- a/autobuild_mac80211_release/package/kernel/mt76/patches/1038-wifi-mt76-update-debugfs-knob-to-dump-token-pending-.patch
+++ /dev/null
@@ -1,77 +0,0 @@
-From d214b1fa6a20455d911bbaecd13292d2a6774d27 Mon Sep 17 00:00:00 2001
-From: Peter Chiu <chui-hao.chiu@mediatek.com>
-Date: Tue, 29 Aug 2023 09:22:18 +0800
-Subject: [PATCH 1038/1048] wifi: mt76: update debugfs knob to dump token
- pending time
-
-Signed-off-by: Peter Chiu <chui-hao.chiu@mediatek.com>
----
- mt76.h               | 2 ++
- mt7915/mac.c         | 6 ++++++
- mt7915/mtk_debugfs.c | 6 ++----
- 3 files changed, 10 insertions(+), 4 deletions(-)
-
-diff --git a/mt76.h b/mt76.h
-index 781be50..aed47c8 100644
---- a/mt76.h
-+++ b/mt76.h
-@@ -402,6 +402,8 @@ struct mt76_txwi_cache {
- 	struct list_head list;
- 	dma_addr_t dma_addr;
- 
-+	unsigned long jiffies;
-+
- 	union {
- 		struct sk_buff *skb;
- 		void *ptr;
-diff --git a/mt7915/mac.c b/mt7915/mac.c
-index e775f61..e1ecefe 100644
---- a/mt7915/mac.c
-+++ b/mt7915/mac.c
-@@ -803,6 +803,8 @@ int mt7915_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
- 	if (id < 0)
- 		return id;
- 
-+	t->jiffies = jiffies;
-+
- 	pid = mt76_tx_status_skb_add(mdev, wcid, tx_info->skb);
- 	mt7915_mac_write_txwi(mdev, txwi_ptr, tx_info->skb, wcid, pid, key,
- 			      qid, 0);
-@@ -1001,6 +1003,8 @@ mt7915_mac_tx_free(struct mt7915_dev *dev, void *data, int len)
- 			if (!txwi)
- 				continue;
- 
-+			txwi->jiffies = 0;
-+
- 			mt76_connac2_txwi_free(mdev, txwi, sta, &free_list);
- 		}
- 	}
-@@ -1033,6 +1037,8 @@ mt7915_mac_tx_free_v0(struct mt7915_dev *dev, void *data, int len)
- 		if (!txwi)
- 			continue;
- 
-+		txwi->jiffies = 0;
-+
- 		mt76_connac2_txwi_free(mdev, txwi, NULL, &free_list);
- 	}
- 
-diff --git a/mt7915/mtk_debugfs.c b/mt7915/mtk_debugfs.c
-index 629b2ac..594989f 100644
---- a/mt7915/mtk_debugfs.c
-+++ b/mt7915/mtk_debugfs.c
-@@ -2209,10 +2209,8 @@ static int mt7915_token_read(struct seq_file *s, void *data)
- 	seq_printf(s, "Cut through token:\n");
- 	spin_lock_bh(&dev->mt76.token_lock);
- 	idr_for_each_entry(&dev->mt76.token, txwi, id) {
--		seq_printf(s, "%4d ", id);
--		count++;
--		if (count % 8 == 0)
--			seq_printf(s, "\n");
-+		seq_printf(s, "%4d (token pending %u ms)\n", id,
-+			   jiffies_to_msecs(jiffies - txwi->jiffies));
- 	}
- 	spin_unlock_bh(&dev->mt76.token_lock);
- 	seq_printf(s, "\n");
--- 
-2.18.0
-