Linux-mediatek Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Sean Wang <sean.wang@kernel.org>
To: Felix Fietkau <nbd@nbd.name>, Lorenzo Bianconi <lorenzo@kernel.org>
Cc: linux-wireless@vger.kernel.org,
	linux-mediatek@lists.infradead.org,
	Sean Wang <sean.wang@mediatek.com>
Subject: [PATCH 4/5] wifi: mt76: usb: add debugfs aggregation stats
Date: Sat, 13 Jun 2026 17:46:54 -0500	[thread overview]
Message-ID: <20260613224655.2405686-5-sean.wang@kernel.org> (raw)
In-Reply-To: <20260613224655.2405686-1-sean.wang@kernel.org>

From: Sean Wang <sean.wang@mediatek.com>

Add USB debugfs counters for RX/TX URBs, packets, bytes and recent RX
aggregation frame counts.

These stats make it easier to verify whether USB RX aggregation are working
as expected, and to debug throughput issues without adding
temporary driver logs.

Signed-off-by: Sean Wang <sean.wang@mediatek.com>
---
 drivers/net/wireless/mediatek/mt76/debugfs.c | 35 ++++++++++++++++++
 drivers/net/wireless/mediatek/mt76/mt76.h    | 12 ++++++
 drivers/net/wireless/mediatek/mt76/usb.c     | 39 ++++++++++++++++++++
 3 files changed, 86 insertions(+)

diff --git a/drivers/net/wireless/mediatek/mt76/debugfs.c b/drivers/net/wireless/mediatek/mt76/debugfs.c
index a5ac6ca86735..b3f1bc3cd69b 100644
--- a/drivers/net/wireless/mediatek/mt76/debugfs.c
+++ b/drivers/net/wireless/mediatek/mt76/debugfs.c
@@ -88,6 +88,38 @@ static int mt76_rx_queues_read(struct seq_file *s, void *data)
 	return 0;
 }
 
+static int mt76_usb_stats_read(struct seq_file *s, void *data)
+{
+	struct mt76_dev *dev = dev_get_drvdata(s->private);
+	struct mt76_usb *usb = &dev->usb;
+	u64 seq;
+	int i, n;
+
+	seq_printf(s, "rx_aggr\t%d\n", usb->rx_aggr.enable);
+	seq_printf(s, "sg_en\t%d\n", usb->sg_en);
+	seq_printf(s, "tx_urbs\t%lld\n", atomic64_read(&usb->stats.tx_urbs));
+	seq_printf(s, "tx_packets\t%lld\n",
+		   atomic64_read(&usb->stats.tx_packets));
+	seq_printf(s, "tx_bytes\t%lld\n", atomic64_read(&usb->stats.tx_bytes));
+	seq_printf(s, "rx_urbs\t%lld\n", atomic64_read(&usb->stats.rx_urbs));
+	seq_printf(s, "rx_packets\t%lld\n",
+		   atomic64_read(&usb->stats.rx_packets));
+	seq_printf(s, "rx_bytes\t%lld\n", atomic64_read(&usb->stats.rx_bytes));
+
+	seq = atomic64_read(&usb->stats.rx_aggr_seq);
+	seq_puts(s, "rx_aggr_nframes");
+	n = min_t(u64, seq, MT_USB_AGGR_STATS_LEN);
+	for (i = 0; i < n; i++) {
+		u64 idx = seq - n + i;
+		u64 slot = idx % MT_USB_AGGR_STATS_LEN;
+
+		seq_printf(s, " %u", READ_ONCE(usb->stats.rx_aggr_nframes[slot]));
+	}
+	seq_puts(s, "\n");
+
+	return 0;
+}
+
 void mt76_seq_puts_array(struct seq_file *file, const char *str,
 			 s8 *val, int len)
 {
@@ -120,6 +152,9 @@ mt76_register_debugfs_fops(struct mt76_phy *phy,
 		debugfs_create_blob("otp", 0400, dir, &dev->otp);
 	debugfs_create_devm_seqfile(dev->dev, "rx-queues", dir,
 				    mt76_rx_queues_read);
+	if (mt76_is_usb(dev))
+		debugfs_create_devm_seqfile(dev->dev, "usb-stats", dir,
+					    mt76_usb_stats_read);
 
 	return dir;
 }
diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
index 125c97dc1f28..c11a463ae092 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -664,6 +664,7 @@ struct mt76u_rx_entry {
 #define MT_RX_SG_MAX_SIZE	4
 #define MT_NUM_TX_ENTRIES	256
 #define MT_NUM_RX_ENTRIES	128
+#define MT_USB_AGGR_STATS_LEN	128
 #define MCU_RESP_URB_SIZE	1024
 struct mt76_usb {
 	struct mutex usb_ctrl_mtx;
@@ -687,6 +688,17 @@ struct mt76_usb {
 		int buf_size;
 	} rx_aggr;
 
+	struct {
+		atomic64_t tx_urbs;
+		atomic64_t tx_packets;
+		atomic64_t tx_bytes;
+		atomic64_t rx_urbs;
+		atomic64_t rx_packets;
+		atomic64_t rx_bytes;
+		atomic64_t rx_aggr_seq;
+		u8 rx_aggr_nframes[MT_USB_AGGR_STATS_LEN];
+	} stats;
+
 	struct mt76u_mcu {
 		u8 *data;
 		/* multiple reads */
diff --git a/drivers/net/wireless/mediatek/mt76/usb.c b/drivers/net/wireless/mediatek/mt76/usb.c
index cbdd663fbb25..10ad2b024985 100644
--- a/drivers/net/wireless/mediatek/mt76/usb.c
+++ b/drivers/net/wireless/mediatek/mt76/usb.c
@@ -15,6 +15,36 @@ static bool disable_usb_sg;
 module_param_named(disable_usb_sg, disable_usb_sg, bool, 0644);
 MODULE_PARM_DESC(disable_usb_sg, "Disable usb scatter-gather support");
 
+static void mt76u_tx_stats_add(struct mt76_dev *dev, struct urb *urb,
+			       unsigned int packets)
+{
+	atomic64_inc(&dev->usb.stats.tx_urbs);
+	atomic64_add(packets, &dev->usb.stats.tx_packets);
+	atomic64_add(urb->transfer_buffer_length, &dev->usb.stats.tx_bytes);
+}
+
+static void mt76u_rx_urb_stats_add(struct mt76_dev *dev, struct urb *urb)
+{
+	atomic64_inc(&dev->usb.stats.rx_urbs);
+	atomic64_add(urb->actual_length, &dev->usb.stats.rx_bytes);
+}
+
+static void mt76u_rx_packet_stats_add(struct mt76_dev *dev,
+				      unsigned int packets)
+{
+	atomic64_add(packets, &dev->usb.stats.rx_packets);
+}
+
+static void mt76u_rx_aggr_stats_add(struct mt76_dev *dev, unsigned int packets)
+{
+	u64 idx, slot;
+
+	idx = atomic64_inc_return(&dev->usb.stats.rx_aggr_seq) - 1;
+	slot = idx % MT_USB_AGGR_STATS_LEN;
+	WRITE_ONCE(dev->usb.stats.rx_aggr_nframes[slot],
+		   min_t(unsigned int, packets, U8_MAX));
+}
+
 int __mt76u_vendor_request(struct mt76_dev *dev, u8 req, u8 req_type,
 			   u16 val, u16 offset, void *buf, size_t len)
 {
@@ -634,6 +664,10 @@ static int mt76u_process_rx_agg_entry(struct mt76_dev *dev, struct urb *urb)
 	mt76_put_page_pool_buf(urb->transfer_buffer, false);
 	urb->transfer_buffer = NULL;
 
+	if (nframes)
+		mt76u_rx_packet_stats_add(dev, nframes);
+	mt76u_rx_aggr_stats_add(dev, nframes);
+
 	return max(nframes, 1);
 }
 
@@ -681,6 +715,7 @@ mt76u_process_rx_entry(struct mt76_dev *dev, struct urb *urb,
 
 	skb_mark_for_recycle(skb);
 	dev->drv->rx_skb(dev, MT_RXQ_MAIN, skb, NULL);
+	mt76u_rx_packet_stats_add(dev, 1);
 
 	return nsgs;
 }
@@ -714,6 +749,9 @@ static void mt76u_complete_rx(struct urb *urb)
 		break;
 	}
 
+	if (!urb->status)
+		mt76u_rx_urb_stats_add(dev, urb);
+
 	spin_lock_irqsave(&q->lock, flags);
 	idx = e - q->entry;
 	pending = q->ndesc - q->queued;
@@ -1083,6 +1121,7 @@ static void mt76u_tx_kick(struct mt76_dev *dev, struct mt76_queue *q)
 					err);
 			break;
 		}
+		mt76u_tx_stats_add(dev, urb, 1);
 		q->first = (q->first + 1) % q->ndesc;
 	}
 }
-- 
2.43.0



  parent reply	other threads:[~2026-06-13 22:47 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-06-13 22:46 [PATCH 0/5] wifi: mt76: add USB RX aggregation support Sean Wang
2026-06-13 22:46 ` [PATCH 1/5] wifi: mt76: usb: size RX page-pool pages from queue buffer Sean Wang
2026-06-13 22:46 ` [PATCH 2/5] wifi: mt76: usb: support out-of-order RX URB completion Sean Wang
2026-06-13 22:46 ` [PATCH 3/5] wifi: mt76: usb: add optional RX aggregation support Sean Wang
2026-06-13 22:46 ` Sean Wang [this message]
2026-06-13 22:46 ` [PATCH 5/5] wifi: mt76: mt7927u: enable USB RX aggregation Sean Wang

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260613224655.2405686-5-sean.wang@kernel.org \
    --to=sean.wang@kernel.org \
    --cc=linux-mediatek@lists.infradead.org \
    --cc=linux-wireless@vger.kernel.org \
    --cc=lorenzo@kernel.org \
    --cc=nbd@nbd.name \
    --cc=sean.wang@mediatek.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox