blob: 8cb87e029e89678d6f890aec6f49f08cb08a4a55 [file] [log] [blame]
From d58cdc551155267c9c57606b0f8098dbcfbb75fc Mon Sep 17 00:00:00 2001
From: Peter Chiu <chui-hao.chiu@mediatek.com>
Date: Mon, 18 Mar 2024 14:16:34 +0800
Subject: [PATCH 1/4] wifi: mt76: add debugfs for tx drop counters
Signed-off-by: Peter Chiu <chui-hao.chiu@mediatek.com>
---
dma.c | 26 +++++++++++++++++++++-----
mt76.h | 22 ++++++++++++++++++++++
mt7915/mac.c | 16 +++++++++++++---
mt7915/mtk_debugfs.c | 37 +++++++++++++++++++++++++++++++++++++
tx.c | 6 ++++++
5 files changed, 99 insertions(+), 8 deletions(-)
diff --git a/dma.c b/dma.c
index d17fc88..da3e8bc 100644
--- a/dma.c
+++ b/dma.c
@@ -612,13 +612,18 @@ mt76_dma_tx_queue_skb(struct mt76_phy *phy, struct mt76_queue *q,
struct sk_buff *iter;
dma_addr_t addr;
u8 *txwi;
+ int reason = -1;
- if (test_bit(MT76_RESET, &phy->state))
+ if (test_bit(MT76_RESET, &phy->state)) {
+ reason = MT_TX_DROP_RESET_STATE;
goto free_skb;
+ }
t = mt76_get_txwi(dev);
- if (!t)
+ if (!t) {
+ reason = MT_TX_DROP_GET_TXWI_FAIL;
goto free_skb;
+ }
txwi = mt76_get_txwi_ptr(dev, t);
@@ -628,8 +633,10 @@ mt76_dma_tx_queue_skb(struct mt76_phy *phy, struct mt76_queue *q,
len = skb_headlen(skb);
addr = dma_map_single(dev->dma_dev, skb->data, len, DMA_TO_DEVICE);
- if (unlikely(dma_mapping_error(dev->dma_dev, addr)))
+ if (unlikely(dma_mapping_error(dev->dma_dev, addr))) {
+ reason = MT_TX_DROP_DMA_FAIL;
goto free;
+ }
tx_info.buf[n].addr = t->dma_addr;
tx_info.buf[n++].len = dev->drv->txwi_size;
@@ -637,13 +644,17 @@ mt76_dma_tx_queue_skb(struct mt76_phy *phy, struct mt76_queue *q,
tx_info.buf[n++].len = len;
skb_walk_frags(skb, iter) {
- if (n == ARRAY_SIZE(tx_info.buf))
+ if (n == ARRAY_SIZE(tx_info.buf)) {
+ reason = MT_TX_DROP_AGG_EXCEEDED;
goto unmap;
+ }
addr = dma_map_single(dev->dma_dev, iter->data, iter->len,
DMA_TO_DEVICE);
- if (unlikely(dma_mapping_error(dev->dma_dev, addr)))
+ if (unlikely(dma_mapping_error(dev->dma_dev, addr))) {
+ reason = MT_TX_DROP_DMA_FAIL;
goto unmap;
+ }
tx_info.buf[n].addr = addr;
tx_info.buf[n++].len = iter->len;
@@ -652,6 +663,7 @@ mt76_dma_tx_queue_skb(struct mt76_phy *phy, struct mt76_queue *q,
if (q->queued + (tx_info.nbuf + 1) / 2 >= q->ndesc - 1) {
ret = -ENOMEM;
+ reason = MT_TX_DROP_RING_FULL;
goto unmap;
}
@@ -663,6 +675,7 @@ mt76_dma_tx_queue_skb(struct mt76_phy *phy, struct mt76_queue *q,
if (ret < 0)
goto unmap;
+ phy->tx_dbg_stats.tx_to_hw++;
return mt76_dma_add_buf(dev, q, tx_info.buf, tx_info.nbuf,
tx_info.info, tx_info.skb, t, NULL);
@@ -690,6 +703,9 @@ free_skb:
ieee80211_tx_status_ext(hw, &status);
spin_unlock_bh(&dev->rx_lock);
+ if (reason >= 0)
+ phy->tx_dbg_stats.tx_drop[reason]++;
+
return ret;
}
diff --git a/mt76.h b/mt76.h
index da5875f..2d59091 100644
--- a/mt76.h
+++ b/mt76.h
@@ -849,6 +849,27 @@ struct mt76_vif {
struct ieee80211_chanctx_conf *ctx;
};
+enum {
+ MT_TX_DROP_IN_TESTMODE,
+ MT_TX_DROP_WCID_NOT_INIT,
+ MT_TX_DROP_STOPPED_QUEUE,
+ MT_TX_DROP_RESET_STATE,
+ MT_TX_DROP_GET_TXWI_FAIL,
+ MT_TX_DROP_DMA_FAIL,
+ MT_TX_DROP_AGG_EXCEEDED,
+ MT_TX_DROP_RING_FULL,
+ MT_TX_DROP_INVALID_SKB,
+ MT_TX_DROP_GET_TOKEN_FAIL,
+ MT_TX_DROP_MAX,
+};
+
+struct mt76_tx_debug {
+ u32 tx_from_mac80211;
+ u32 tx_to_hw;
+
+ u32 tx_drop[MT_TX_DROP_MAX];
+};
+
struct mt76_phy {
struct ieee80211_hw *hw;
struct mt76_dev *dev;
@@ -906,6 +927,7 @@ struct mt76_phy {
u8 pin;
} leds;
int tokens;
+ struct mt76_tx_debug tx_dbg_stats;
};
struct mt76_dev {
diff --git a/mt7915/mac.c b/mt7915/mac.c
index 0c12170..1e2ef8c 100644
--- a/mt7915/mac.c
+++ b/mt7915/mac.c
@@ -782,9 +782,15 @@ int mt7915_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
u8 phy_idx = (info->hw_queue & MT_TX_HW_QUEUE_PHY) >> 2;
u8 *txwi = (u8 *)txwi_ptr;
int pid;
+ struct mt76_phy *mphy = &mdev->phy;
- if (unlikely(tx_info->skb->len <= ETH_HLEN))
+ if (phy_idx && mdev->phys[MT_BAND1])
+ mphy = mdev->phys[MT_BAND1];
+
+ if (unlikely(tx_info->skb->len <= ETH_HLEN)) {
+ mphy->tx_dbg_stats.tx_drop[MT_TX_DROP_INVALID_SKB]++;
return -EINVAL;
+ }
if (!wcid)
wcid = &dev->mt76.global_wcid;
@@ -804,12 +810,16 @@ int mt7915_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
t->skb = tx_info->skb;
if (ieee80211_is_action(fc) &&
- mgmt->u.action.category == 0xff)
+ mgmt->u.action.category == 0xff) {
+ mphy->tx_dbg_stats.tx_drop[MT_TX_DROP_INVALID_SKB]++;
return -1;
+ }
id = mt76_token_consume(mdev, &t, phy_idx);
- if (id < 0)
+ if (id < 0) {
+ mphy->tx_dbg_stats.tx_drop[MT_TX_DROP_GET_TOKEN_FAIL]++;
return id;
+ }
t->jiffies = jiffies;
diff --git a/mt7915/mtk_debugfs.c b/mt7915/mtk_debugfs.c
index 2c9f198..1b2fbf9 100644
--- a/mt7915/mtk_debugfs.c
+++ b/mt7915/mtk_debugfs.c
@@ -4033,6 +4033,12 @@ static int mt7915_reset_counter(void *data, u64 val)
struct mt7915_dev *dev = phy->dev;
struct mt76_wcid *wcid;
+ if (!dev->wlan_idx) {
+ memset(&phy->mt76->tx_dbg_stats, 0, sizeof(struct mt76_tx_debug));
+
+ return 0;
+ }
+
/* Clear the firmware counters */
mt7915_mcu_wed_wa_tx_stats(dev, dev->wlan_idx, NULL);
mt7915_get_tx_stat(phy, dev->wlan_idx);
@@ -4087,6 +4093,35 @@ mt7915_per_read(struct seq_file *s, void *data)
return 0;
}
+static int
+mt7915_tx_drop_show(struct seq_file *s, void *data)
+{
+ struct mt7915_phy *phy = s->private;
+ struct mt76_tx_debug *stats = &phy->mt76->tx_dbg_stats;
+
+ seq_printf(s, "Receive from mac80211: %d\n", stats->tx_from_mac80211);
+ seq_printf(s, "Send to hw: %d\n", stats->tx_to_hw);
+
+#define __pr(t) seq_printf(s, "Drop due to %s: %d\n", \
+ #t, stats->tx_drop[MT_TX_DROP_##t])
+ __pr(IN_TESTMODE);
+ __pr(WCID_NOT_INIT);
+ __pr(STOPPED_QUEUE);
+ __pr(RESET_STATE);
+ __pr(GET_TXWI_FAIL);
+ __pr(DMA_FAIL);
+ __pr(AGG_EXCEEDED);
+ __pr(RING_FULL);
+ __pr(INVALID_SKB);
+ __pr(GET_TOKEN_FAIL);
+
+#undef __pr
+
+ return 0;
+}
+
+DEFINE_SHOW_ATTRIBUTE(mt7915_tx_drop);
+
int mt7915_mtk_init_debugfs(struct mt7915_phy *phy, struct dentry *dir)
{
struct mt7915_dev *dev = phy->dev;
@@ -4186,7 +4221,9 @@ int mt7915_mtk_init_debugfs(struct mt7915_phy *phy, struct dentry *dir)
debugfs_create_file("sr_scene_cond", 0400, dir, phy, &mt7915_sr_scene_cond_fops);
debugfs_create_file("reset_counter", 0200, dir, phy, &fops_reset_counter);
debugfs_create_devm_seqfile(dev->mt76.dev, "per", dir, mt7915_per_read);
+ debugfs_create_file("tx_drop_stats", 0400, dir, phy, &mt7915_tx_drop_fops);
return 0;
}
+
#endif
diff --git a/tx.c b/tx.c
index df2bb07..e4eb74b 100644
--- a/tx.c
+++ b/tx.c
@@ -330,8 +330,10 @@ mt76_tx(struct mt76_phy *phy, struct ieee80211_sta *sta,
{
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+ phy->tx_dbg_stats.tx_from_mac80211++;
if (mt76_testmode_enabled(phy)) {
ieee80211_free_txskb(phy->hw, skb);
+ phy->tx_dbg_stats.tx_drop[MT_TX_DROP_IN_TESTMODE]++;
return;
}
@@ -348,6 +350,7 @@ mt76_tx(struct mt76_phy *phy, struct ieee80211_sta *sta,
dev_warn(phy->dev->dev, "Un-initialized STA %pM wcid %d in mt76_tx\n",
sta->addr, wcid->idx);
+ phy->tx_dbg_stats.tx_drop[MT_TX_DROP_WCID_NOT_INIT]++;
ieee80211_free_txskb(phy->hw, skb);
return;
}
@@ -379,6 +382,8 @@ mt76_txq_dequeue(struct mt76_phy *phy, struct mt76_txq *mtxq)
info = IEEE80211_SKB_CB(skb);
info->hw_queue |= FIELD_PREP(MT_TX_HW_QUEUE_PHY, phy->band_idx);
+ phy->tx_dbg_stats.tx_from_mac80211++;
+
return skb;
}
@@ -616,6 +621,7 @@ mt76_txq_schedule_pending_wcid(struct mt76_phy *phy, struct mt76_wcid *wcid)
q = phy->q_tx[qid];
if (mt76_txq_stopped(q)) {
ret = -1;
+ phy->tx_dbg_stats.tx_drop[MT_TX_DROP_STOPPED_QUEUE]++;
break;
}
--
2.18.0