blob: af71cc87e8177ddeacd19e861477690950f9f7d9 [file] [log] [blame]
developer05f3b2b2024-08-19 19:17:34 +08001From a56b55265b3e813f7b803b242094a9a9a77cd3a4 Mon Sep 17 00:00:00 2001
2From: Peter Chiu <chui-hao.chiu@mediatek.com>
3Date: Thu, 13 Jun 2024 17:47:13 +0800
4Subject: [PATCH 164/199] mtk: mt76: add debugfs for tx drop counters
5
6Signed-off-by: Peter Chiu <chui-hao.chiu@mediatek.com>
7---
8 dma.c | 22 +++++++++---
9 mac80211.c | 2 ++
10 mt76.h | 27 +++++++++++++++
11 mt7996/mac.c | 20 ++++++++---
12 mt7996/main.c | 10 ++++--
13 mt7996/mtk_debugfs.c | 80 ++++++++++++++++++++++++++++++++++++++++++++
14 tx.c | 12 +++++++
15 7 files changed, 161 insertions(+), 12 deletions(-)
16
17diff --git a/dma.c b/dma.c
18index 3f1fb6c2..0dae40e2 100644
19--- a/dma.c
20+++ b/dma.c
21@@ -612,12 +612,16 @@ mt76_dma_tx_queue_skb(struct mt76_phy *phy, struct mt76_queue *q,
22 dma_addr_t addr;
23 u8 *txwi;
24
25- if (test_bit(MT76_RESET, &phy->state))
26+ if (test_bit(MT76_RESET, &phy->state)) {
27+ phy->tx_dbg_stats.tx_drop[MT_TX_DROP_RESET_STATE]++;
28 goto free_skb;
29+ }
30
31 t = mt76_get_txwi(dev);
32- if (!t)
33+ if (!t) {
34+ dev->tx_dbg_stats.tx_drop[MT_TX_DROP_GET_TXWI_FAIL]++;
35 goto free_skb;
36+ }
37
38 txwi = mt76_get_txwi_ptr(dev, t);
39
40@@ -627,8 +631,10 @@ mt76_dma_tx_queue_skb(struct mt76_phy *phy, struct mt76_queue *q,
41
42 len = skb_headlen(skb);
43 addr = dma_map_single(dev->dma_dev, skb->data, len, DMA_TO_DEVICE);
44- if (unlikely(dma_mapping_error(dev->dma_dev, addr)))
45+ if (unlikely(dma_mapping_error(dev->dma_dev, addr))) {
46+ dev->tx_dbg_stats.tx_drop[MT_TX_DROP_DMA_FAIL]++;
47 goto free;
48+ }
49
50 tx_info.buf[n].addr = t->dma_addr;
51 tx_info.buf[n++].len = dev->drv->txwi_size;
52@@ -636,13 +642,17 @@ mt76_dma_tx_queue_skb(struct mt76_phy *phy, struct mt76_queue *q,
53 tx_info.buf[n++].len = len;
54
55 skb_walk_frags(skb, iter) {
56- if (n == ARRAY_SIZE(tx_info.buf))
57+ if (n == ARRAY_SIZE(tx_info.buf)) {
58+ dev->tx_dbg_stats.tx_drop[MT_TX_DROP_AGG_EXCEEDED]++;
59 goto unmap;
60+ }
61
62 addr = dma_map_single(dev->dma_dev, iter->data, iter->len,
63 DMA_TO_DEVICE);
64- if (unlikely(dma_mapping_error(dev->dma_dev, addr)))
65+ if (unlikely(dma_mapping_error(dev->dma_dev, addr))) {
66+ dev->tx_dbg_stats.tx_drop[MT_TX_DROP_DMA_FAIL]++;
67 goto unmap;
68+ }
69
70 tx_info.buf[n].addr = addr;
71 tx_info.buf[n++].len = iter->len;
72@@ -651,6 +661,7 @@ mt76_dma_tx_queue_skb(struct mt76_phy *phy, struct mt76_queue *q,
73
74 if (q->queued + (tx_info.nbuf + 1) / 2 >= q->ndesc - 1) {
75 ret = -ENOMEM;
76+ phy->tx_dbg_stats.tx_drop[MT_TX_DROP_RING_FULL]++;
77 goto unmap;
78 }
79
80@@ -662,6 +673,7 @@ mt76_dma_tx_queue_skb(struct mt76_phy *phy, struct mt76_queue *q,
81 if (ret < 0)
82 goto unmap;
83
84+ phy->tx_dbg_stats.tx_to_hw++;
85 return mt76_dma_add_buf(dev, q, tx_info.buf, tx_info.nbuf,
86 tx_info.info, tx_info.skb, t);
87
88diff --git a/mac80211.c b/mac80211.c
89index 10267019..5402366e 100644
90--- a/mac80211.c
91+++ b/mac80211.c
92@@ -417,6 +417,7 @@ mt76_phy_init(struct mt76_phy *phy, struct ieee80211_hw *hw)
93
94 INIT_LIST_HEAD(&phy->tx_list);
95 spin_lock_init(&phy->tx_lock);
96+ spin_lock_init(&phy->tx_dbg_stats.lock);
97
98 SET_IEEE80211_DEV(hw, dev->dev);
99 SET_IEEE80211_PERM_ADDR(hw, phy->macaddr);
100@@ -597,6 +598,7 @@ mt76_alloc_device(struct device *pdev, unsigned int size,
101 spin_lock_init(&dev->lock);
102 spin_lock_init(&dev->cc_lock);
103 spin_lock_init(&dev->status_lock);
104+ spin_lock_init(&dev->tx_dbg_stats.lock);
105 mutex_init(&dev->mutex);
106 init_waitqueue_head(&dev->tx_wait);
107
108diff --git a/mt76.h b/mt76.h
109index 728740ef..ee118ee5 100644
110--- a/mt76.h
111+++ b/mt76.h
112@@ -835,6 +835,31 @@ struct mt76_vif {
113 struct ieee80211_chanctx_conf *ctx;
114 };
115
116+enum {
117+ MT_TX_DROP_IN_TESTMODE,
118+ MT_TX_DROP_WCID_NOT_INIT,
119+ MT_TX_DROP_STOPPED_QUEUE,
120+ MT_TX_DROP_RESET_STATE,
121+ MT_TX_DROP_GET_TXWI_FAIL,
122+ MT_TX_DROP_DMA_FAIL,
123+ MT_TX_DROP_AGG_EXCEEDED,
124+ MT_TX_DROP_RING_FULL,
125+ MT_TX_DROP_INVALID_SKB,
126+ MT_TX_DROP_GET_TOKEN_FAIL,
127+ MT_TX_DROP_ADDR_TRANS_FAIL,
128+ MT_TX_DROP_INVALID_WCID,
129+ MT_TX_DROP_INVALID_LINK,
130+ MT_TX_DROP_MAX,
131+};
132+
133+struct mt76_tx_debug {
134+ u32 tx_from_mac80211;
135+ u32 tx_to_hw;
136+
137+ u32 tx_drop[MT_TX_DROP_MAX];
138+ spinlock_t lock;
139+};
140+
141 struct mt76_phy {
142 struct ieee80211_hw *hw;
143 struct ieee80211_hw *ori_hw;
144@@ -891,6 +916,7 @@ struct mt76_phy {
145 bool al;
146 u8 pin;
147 } leds;
148+ struct mt76_tx_debug tx_dbg_stats;
149 };
150
151 struct mt76_dev {
152@@ -995,6 +1021,7 @@ struct mt76_dev {
153 };
154
155 const char *bin_file_name;
156+ struct mt76_tx_debug tx_dbg_stats;
157 };
158
159 #define MT76_MAX_AMSDU_NUM 8
160diff --git a/mt7996/mac.c b/mt7996/mac.c
161index 017e3465..0f282f16 100644
162--- a/mt7996/mac.c
163+++ b/mt7996/mac.c
164@@ -897,11 +897,15 @@ int mt7996_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
165 u8 *txwi = (u8 *)txwi_ptr;
166 u8 link_id;
167
168- if (unlikely(tx_info->skb->len <= ETH_HLEN))
169+ if (unlikely(tx_info->skb->len <= ETH_HLEN)) {
170+ mdev->tx_dbg_stats.tx_drop[MT_TX_DROP_INVALID_SKB]++;
171 return -EINVAL;
172+ }
173
174- if (WARN_ON(!wcid))
175+ if (WARN_ON(!wcid)) {
176+ mdev->tx_dbg_stats.tx_drop[MT_TX_DROP_INVALID_WCID]++;
177 return -EINVAL;
178+ }
179
180 msta = sta ? (struct mt7996_sta *)sta->drv_priv : &mvif->sta;
181 if (ieee80211_is_data_qos(hdr->frame_control) && sta->mlo) {
182@@ -927,15 +931,19 @@ int mt7996_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
183 }
184
185 mconf = rcu_dereference(mvif->link[wcid->link_id]);
186- if (!mconf)
187+ if (!mconf) {
188+ mdev->tx_dbg_stats.tx_drop[MT_TX_DROP_INVALID_LINK]++;
189 return -ENOLINK;
190+ }
191
192 t = (struct mt76_txwi_cache *)(txwi + mdev->drv->txwi_size);
193 t->skb = tx_info->skb;
194
195 id = mt76_token_consume(mdev, &t);
196- if (id < 0)
197+ if (id < 0) {
198+ mdev->tx_dbg_stats.tx_drop[MT_TX_DROP_GET_TOKEN_FAIL]++;
199 return id;
200+ }
201 #ifdef CONFIG_MTK_DEBUG
202 t->jiffies = jiffies;
203 #endif
204@@ -957,8 +965,10 @@ int mt7996_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
205
206 conf = rcu_dereference(vif->link_conf[wcid->link_id]);
207 link_sta = rcu_dereference(sta->link[wcid->link_id]);
208- if (!conf || !link_sta)
209+ if (!conf || !link_sta) {
210+ mdev->tx_dbg_stats.tx_drop[MT_TX_DROP_INVALID_LINK]++;
211 return -ENOLINK;
212+ }
213
214 dma_sync_single_for_cpu(mdev->dma_dev, tx_info->buf[1].addr,
215 tx_info->buf[1].len, DMA_TO_DEVICE);
216diff --git a/mt7996/main.c b/mt7996/main.c
217index 443b3962..553345e8 100644
218--- a/mt7996/main.c
219+++ b/mt7996/main.c
220@@ -1423,11 +1423,13 @@ static void mt7996_tx(struct ieee80211_hw *hw,
221 struct sk_buff *skb)
222 {
223 struct mt76_phy *mphy;
224+ struct mt7996_dev *dev = mt7996_hw_dev(hw);
225 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
226 struct ieee80211_vif *vif = info->control.vif;
227 struct mt76_wcid *wcid;
228 struct mt7996_vif *mvif;
229 struct mt7996_sta *msta;
230+ bool addr_trans_success = false;
231
232 if (control->sta) {
233 msta = (struct mt7996_sta *)control->sta->drv_priv;
234@@ -1499,14 +1501,18 @@ static void mt7996_tx(struct ieee80211_hw *hw,
235 mphy = mconf->phy->mt76;
236 wcid = &mlink->wcid;
237 } else {
238- struct mt7996_dev *dev = mt7996_hw_dev(hw);
239-
240 mphy = hw->priv;
241 wcid = &dev->mt76.global_wcid;
242 }
243
244+ addr_trans_success = true;
245 mt76_tx(mphy, control->sta, wcid, skb);
246 unlock:
247+ if (!addr_trans_success) {
248+ spin_lock_bh(&dev->mt76.tx_dbg_stats.lock);
249+ dev->mt76.tx_dbg_stats.tx_drop[MT_TX_DROP_ADDR_TRANS_FAIL]++;
250+ spin_unlock_bh(&dev->mt76.tx_dbg_stats.lock);
251+ }
252 rcu_read_unlock();
253 }
254
255diff --git a/mt7996/mtk_debugfs.c b/mt7996/mtk_debugfs.c
256index 9bd35c91..759b9d8f 100644
257--- a/mt7996/mtk_debugfs.c
258+++ b/mt7996/mtk_debugfs.c
259@@ -4163,6 +4163,83 @@ out:
260 return ret;
261 }
262
263+static int
264+mt7996_tx_drop_show(struct seq_file *s, void *data)
265+{
266+ struct mt7996_dev *dev = s->private;
267+ struct mt76_dev *mdev = &dev->mt76;
268+ struct mt76_tx_debug *dev_stats = &mdev->tx_dbg_stats;
269+ struct mt76_tx_debug *phy_stats[__MT_MAX_BAND];
270+ int i = 0;
271+
272+ seq_printf(s, "\t\t\t\t dev");
273+ for (i = 0; i < __MT_MAX_BAND; i++) {
274+ seq_printf(s, " Band%d", i);
275+ if (mdev->phys[i]) {
276+ phy_stats[i] = &mdev->phys[i]->tx_dbg_stats;
277+ } else {
278+ phy_stats[i] = kzalloc(sizeof(struct mt76_tx_debug),
279+ GFP_KERNEL);
280+ if (!phy_stats[i])
281+ goto out;
282+ }
283+
284+ }
285+ seq_printf(s, " total\n");
286+
287+ seq_printf(s, "%-30s%12d%12d%12d%12d%12d\n", "Receive from mac80211",
288+ dev_stats->tx_from_mac80211,
289+ phy_stats[0]->tx_from_mac80211,
290+ phy_stats[1]->tx_from_mac80211,
291+ phy_stats[2]->tx_from_mac80211,
292+ dev_stats->tx_from_mac80211 +
293+ phy_stats[0]->tx_from_mac80211 +
294+ phy_stats[1]->tx_from_mac80211 +
295+ phy_stats[2]->tx_from_mac80211);
296+ seq_printf(s, "%-30s%12d%12d%12d%12d%12d\n\n", "Send to hw",
297+ dev_stats->tx_to_hw,
298+ phy_stats[0]->tx_to_hw,
299+ phy_stats[1]->tx_to_hw,
300+ phy_stats[2]->tx_to_hw,
301+ dev_stats->tx_to_hw +
302+ phy_stats[0]->tx_to_hw +
303+ phy_stats[1]->tx_to_hw +
304+ phy_stats[2]->tx_to_hw);
305+#define __pr(t) seq_printf(s, "Drop due to %-18s%12d%12d%12d%12d%12d\n",\
306+ #t, dev_stats->tx_drop[MT_TX_DROP_##t], \
307+ phy_stats[0]->tx_drop[MT_TX_DROP_##t], \
308+ phy_stats[1]->tx_drop[MT_TX_DROP_##t], \
309+ phy_stats[2]->tx_drop[MT_TX_DROP_##t], \
310+ dev_stats->tx_drop[MT_TX_DROP_##t] + \
311+ phy_stats[0]->tx_drop[MT_TX_DROP_##t] + \
312+ phy_stats[1]->tx_drop[MT_TX_DROP_##t] + \
313+ phy_stats[2]->tx_drop[MT_TX_DROP_##t])
314+
315+ __pr(IN_TESTMODE);
316+ __pr(WCID_NOT_INIT);
317+ __pr(STOPPED_QUEUE);
318+ __pr(RESET_STATE);
319+ __pr(GET_TXWI_FAIL);
320+ __pr(DMA_FAIL);
321+ __pr(AGG_EXCEEDED);
322+ __pr(RING_FULL);
323+ __pr(INVALID_SKB);
324+ __pr(GET_TOKEN_FAIL);
325+ __pr(ADDR_TRANS_FAIL);
326+ __pr(INVALID_WCID);
327+ __pr(INVALID_LINK);
328+
329+#undef __pr
330+out:
331+ for (i = 0; i < __MT_MAX_BAND; i++) {
332+ if (!mdev->phys[i] && phy_stats[i])
333+ kfree(phy_stats[i]);
334+ }
335+
336+ return 0;
337+}
338+DEFINE_SHOW_ATTRIBUTE(mt7996_tx_drop);
339+
340 /* DRR */
341 static int
342 mt7996_drr_info(struct seq_file *s, void *data)
343@@ -4288,6 +4365,9 @@ void mt7996_mtk_init_dev_debugfs(struct mt7996_dev *dev, struct dentry *dir)
344 /* amsdu */
345 debugfs_create_file("amsdu_algo", 0600, dir, dev, &fops_amsdu_algo);
346 debugfs_create_file("amsdu_para", 0600, dir, dev, &fops_amsdu_para);
347+
348+ /* Drop counters */
349+ debugfs_create_file("tx_drop_stats", 0400, dir, dev, &mt7996_tx_drop_fops);
350 }
351
352 #endif
353diff --git a/tx.c b/tx.c
354index 6580833e..5e6e433f 100644
355--- a/tx.c
356+++ b/tx.c
357@@ -331,8 +331,14 @@ mt76_tx(struct mt76_phy *phy, struct ieee80211_sta *sta,
358 {
359 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
360
361+ spin_lock_bh(&phy->tx_dbg_stats.lock);
362+ phy->tx_dbg_stats.tx_from_mac80211++;
363+ spin_unlock_bh(&phy->tx_dbg_stats.lock);
364 if (mt76_testmode_enabled(phy)) {
365 ieee80211_free_txskb(phy->hw, skb);
366+ spin_lock_bh(&phy->tx_dbg_stats.lock);
367+ phy->tx_dbg_stats.tx_drop[MT_TX_DROP_IN_TESTMODE]++;
368+ spin_unlock_bh(&phy->tx_dbg_stats.lock);
369 return;
370 }
371
372@@ -349,6 +355,9 @@ mt76_tx(struct mt76_phy *phy, struct ieee80211_sta *sta,
373 dev_warn(phy->dev->dev, "Un-initialized STA %pM wcid %d in mt76_tx\n",
374 sta->addr, wcid->idx);
375
376+ spin_lock_bh(&phy->tx_dbg_stats.lock);
377+ phy->tx_dbg_stats.tx_drop[MT_TX_DROP_WCID_NOT_INIT]++;
378+ spin_unlock_bh(&phy->tx_dbg_stats.lock);
379 ieee80211_free_txskb(phy->hw, skb);
380 return;
381 }
382@@ -380,6 +389,8 @@ mt76_txq_dequeue(struct mt76_phy *phy, struct mt76_txq *mtxq)
383 info = IEEE80211_SKB_CB(skb);
384 info->hw_queue |= FIELD_PREP(MT_TX_HW_QUEUE_PHY, phy->band_idx);
385
386+ phy->dev->tx_dbg_stats.tx_from_mac80211++;
387+
388 return skb;
389 }
390
391@@ -617,6 +628,7 @@ mt76_txq_schedule_pending_wcid(struct mt76_phy *phy, struct mt76_wcid *wcid)
392 q = phy->q_tx[qid];
393 if (mt76_txq_stopped(q)) {
394 ret = -1;
395+ phy->tx_dbg_stats.tx_drop[MT_TX_DROP_STOPPED_QUEUE]++;
396 break;
397 }
398
399--
4002.18.0
401