blob: fdefbb3a658807ec4e7e53ac5b128047f2a63fa4 [file] [log] [blame]
From 92db3705c71472d0b822f9aa650ca893b55a5aaf Mon Sep 17 00:00:00 2001
From: Peter Chiu <chui-hao.chiu@mediatek.com>
Date: Fri, 28 Apr 2023 10:39:58 +0800
Subject: [PATCH 1029/1044] mtk: wifi: mt76: mt7996: add debugfs knob for
rx_counters
Signed-off-by: Peter Chiu <chui-hao.chiu@mediatek.com>
---
agg-rx.c | 8 ++++++++
mac80211.c | 16 ++++++++++++++--
mt76.h | 15 +++++++++++++++
mt7996/mac.c | 18 +++++++++++++++---
mt7996/mtk_debugfs.c | 42 ++++++++++++++++++++++++++++++++++++++++++
5 files changed, 94 insertions(+), 5 deletions(-)
diff --git a/agg-rx.c b/agg-rx.c
index 10cbd9e5..adb5a7d7 100644
--- a/agg-rx.c
+++ b/agg-rx.c
@@ -33,10 +33,13 @@ mt76_rx_aggr_release_frames(struct mt76_rx_tid *tid,
struct sk_buff_head *frames,
u16 head)
{
+ struct mt76_phy *phy = mt76_dev_phy(tid->dev, tid->band_idx);
int idx;
while (ieee80211_sn_less(tid->head, head)) {
idx = tid->head % tid->size;
+ if (!tid->reorder_buf[idx])
+ phy->rx_stats.rx_agg_miss++;
mt76_aggr_release(tid, frames, idx);
}
}
@@ -151,6 +154,7 @@ void mt76_rx_aggr_reorder(struct sk_buff *skb, struct sk_buff_head *frames)
struct mt76_wcid *wcid = status->wcid;
struct ieee80211_sta *sta;
struct mt76_rx_tid *tid;
+ struct mt76_phy *phy;
bool sn_less;
u16 seqno, head, size, idx;
u8 tidno = status->qos_ctl & IEEE80211_QOS_CTL_TID_MASK;
@@ -186,6 +190,7 @@ void mt76_rx_aggr_reorder(struct sk_buff *skb, struct sk_buff_head *frames)
head = tid->head;
seqno = status->seqno;
size = tid->size;
+ phy = mt76_dev_phy(tid->dev, tid->band_idx);
sn_less = ieee80211_sn_less(seqno, head);
if (!tid->started) {
@@ -197,6 +202,7 @@ void mt76_rx_aggr_reorder(struct sk_buff *skb, struct sk_buff_head *frames)
if (sn_less) {
__skb_unlink(skb, frames);
+ phy->rx_stats.rx_dup_drop++;
dev_kfree_skb(skb);
goto out;
}
@@ -223,6 +229,7 @@ void mt76_rx_aggr_reorder(struct sk_buff *skb, struct sk_buff_head *frames)
/* Discard if the current slot is already in use */
if (tid->reorder_buf[idx]) {
+ phy->rx_stats.rx_dup_drop++;
dev_kfree_skb(skb);
goto out;
}
@@ -254,6 +261,7 @@ int mt76_rx_aggr_start(struct mt76_dev *dev, struct mt76_wcid *wcid, u8 tidno,
tid->head = ssn;
tid->size = size;
tid->num = tidno;
+ tid->band_idx = wcid->phy_idx;
INIT_DELAYED_WORK(&tid->reorder_work, mt76_rx_aggr_reorder_work);
spin_lock_init(&tid->lock);
diff --git a/mac80211.c b/mac80211.c
index e7d02d15..ae040ec4 100644
--- a/mac80211.c
+++ b/mac80211.c
@@ -784,6 +784,7 @@ static void mt76_rx_release_amsdu(struct mt76_phy *phy, enum mt76_rxq_id q)
}
if (ether_addr_equal(skb->data + offset, rfc1042_header)) {
+ phy->rx_stats.rx_drop++;
dev_kfree_skb(skb);
return;
}
@@ -1100,10 +1101,16 @@ mt76_rx_convert(struct mt76_dev *dev, struct sk_buff *skb,
*sta = wcid_to_sta(mstat.wcid);
*hw = mt76_phy_hw(dev, mstat.phy_idx);
+
+ if ((mstat.flag & RX_FLAG_8023) || ieee80211_is_data_qos(hdr->frame_control)) {
+ struct mt76_phy *phy = mt76_dev_phy(dev, mstat.phy_idx);
+
+ phy->rx_stats.rx_mac80211++;
+ }
}
static void
-mt76_check_ccmp_pn(struct sk_buff *skb)
+mt76_check_ccmp_pn(struct mt76_dev *dev, struct sk_buff *skb)
{
struct mt76_rx_status *status = (struct mt76_rx_status *)skb->cb;
struct mt76_wcid *wcid = status->wcid;
@@ -1150,7 +1157,11 @@ skip_hdr_check:
ret = memcmp(status->iv, wcid->rx_key_pn[security_idx],
sizeof(status->iv));
if (ret <= 0) {
+ struct mt76_phy *phy = mt76_dev_phy(dev, status->phy_idx);
+
+ phy->rx_stats.rx_pn_iv_error++;
status->flag |= RX_FLAG_ONLY_MONITOR;
+
return;
}
@@ -1331,7 +1342,7 @@ void mt76_rx_complete(struct mt76_dev *dev, struct sk_buff_head *frames,
while ((skb = __skb_dequeue(frames)) != NULL) {
struct sk_buff *nskb = skb_shinfo(skb)->frag_list;
- mt76_check_ccmp_pn(skb);
+ mt76_check_ccmp_pn(dev, skb);
skb_shinfo(skb)->frag_list = NULL;
mt76_rx_convert(dev, skb, &hw, &sta);
ieee80211_rx_list(hw, sta, skb, &list);
@@ -1354,6 +1365,7 @@ void mt76_rx_complete(struct mt76_dev *dev, struct sk_buff_head *frames,
}
list_for_each_entry_safe(skb, tmp, &list, list) {
+ dev->rx_kernel++;
skb_list_del_init(skb);
napi_gro_receive(napi, skb);
}
diff --git a/mt76.h b/mt76.h
index b0211879..6ace1a05 100644
--- a/mt76.h
+++ b/mt76.h
@@ -423,6 +423,7 @@ struct mt76_rx_tid {
struct rcu_head rcu_head;
struct mt76_dev *dev;
+ u8 band_idx;
spinlock_t lock;
struct delayed_work reorder_work;
@@ -854,6 +855,19 @@ struct mt76_phy {
bool al;
u8 pin;
} leds;
+
+ struct {
+ u32 rx_mac80211;
+
+ u32 rx_drop;
+ u32 rx_rxd_drop;
+ u32 rx_dup_drop;
+ u32 rx_agg_miss;
+ u32 rx_icv_error;
+ u32 rx_fcs_error;
+ u32 rx_tkip_mic_error;
+ u32 rx_pn_iv_error;
+ } rx_stats;
};
struct mt76_dev {
@@ -959,6 +973,7 @@ struct mt76_dev {
};
const char *bin_file_name;
+ u32 rx_kernel;
};
/* per-phy stats. */
diff --git a/mt7996/mac.c b/mt7996/mac.c
index dc806892..34dea859 100644
--- a/mt7996/mac.c
+++ b/mt7996/mac.c
@@ -469,8 +469,10 @@ mt7996_mac_fill_rx(struct mt7996_dev *dev, enum mt76_rxq_id q,
return -EINVAL;
/* ICV error or CCMP/BIP/WPI MIC error */
- if (rxd1 & MT_RXD1_NORMAL_ICV_ERR)
+ if (rxd1 & MT_RXD1_NORMAL_ICV_ERR) {
+ mphy->rx_stats.rx_icv_error++;
status->flag |= RX_FLAG_ONLY_MONITOR;
+ }
unicast = FIELD_GET(MT_RXD3_NORMAL_ADDR_TYPE, rxd3) == MT_RXD3_NORMAL_U2M;
idx = FIELD_GET(MT_RXD1_NORMAL_WLAN_IDX, rxd1);
@@ -501,11 +503,15 @@ mt7996_mac_fill_rx(struct mt7996_dev *dev, enum mt76_rxq_id q,
!(csum_status & (BIT(0) | BIT(2) | BIT(3))))
skb->ip_summed = CHECKSUM_UNNECESSARY;
- if (rxd1 & MT_RXD3_NORMAL_FCS_ERR)
+ if (rxd1 & MT_RXD3_NORMAL_FCS_ERR) {
+ mphy->rx_stats.rx_fcs_error++;
status->flag |= RX_FLAG_FAILED_FCS_CRC;
+ }
- if (rxd1 & MT_RXD1_NORMAL_TKIP_MIC_ERR)
+ if (rxd1 & MT_RXD1_NORMAL_TKIP_MIC_ERR) {
+ mphy->rx_stats.rx_tkip_mic_error++;
status->flag |= RX_FLAG_MMIC_ERROR;
+ }
if (FIELD_GET(MT_RXD2_NORMAL_SEC_MODE, rxd2) != 0 &&
!(rxd1 & (MT_RXD1_NORMAL_CLM | MT_RXD1_NORMAL_CM))) {
@@ -1415,8 +1421,10 @@ void mt7996_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q,
struct sk_buff *skb, u32 *info)
{
struct mt7996_dev *dev = container_of(mdev, struct mt7996_dev, mt76);
+ struct mt76_phy *phy;
__le32 *rxd = (__le32 *)skb->data;
__le32 *end = (__le32 *)&skb->data[skb->len];
+ u8 band_idx;
enum rx_pkt_type type;
type = le32_get_bits(rxd[0], MT_RXD0_PKT_TYPE);
@@ -1458,6 +1466,10 @@ void mt7996_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q,
}
fallthrough;
default:
+ band_idx = le32_get_bits(rxd[1], MT_RXD1_NORMAL_BAND_IDX);
+ phy = mt76_dev_phy(mdev, band_idx);
+ if (likely(phy))
+ phy->rx_stats.rx_rxd_drop++;
dev_kfree_skb(skb);
break;
}
diff --git a/mt7996/mtk_debugfs.c b/mt7996/mtk_debugfs.c
index d1ca9ce7..17bbed65 100644
--- a/mt7996/mtk_debugfs.c
+++ b/mt7996/mtk_debugfs.c
@@ -2854,6 +2854,46 @@ mt7996_sr_scene_cond_show(struct seq_file *file, void *data)
}
DEFINE_SHOW_ATTRIBUTE(mt7996_sr_scene_cond);
+static int mt7996_rx_counters(struct seq_file *s, void *data)
+{
+ struct mt7996_dev *dev = dev_get_drvdata(s->private);
+ u32 rx_mac80211 = 0;
+ int i = 0;
+
+ for (i = 0; i < __MT_MAX_BAND; i++) {
+ struct mt76_phy *phy = mt76_dev_phy(&dev->mt76, i);
+
+ if (!phy)
+ continue;
+
+ seq_printf(s, "\n==========PHY%d==========\n", i);
+
+#define SEQ_PRINT(_str, _rx_param) do { \
+ seq_printf(s, _str"\n", phy->rx_stats._rx_param); \
+ } while (0)
+
+ SEQ_PRINT("Rx to mac80211: %u", rx_mac80211);
+ SEQ_PRINT("Rx drop: %u", rx_drop);
+ SEQ_PRINT("Rx drop due to RXD type error: %u", rx_rxd_drop);
+ SEQ_PRINT("Rx duplicated drop: %u", rx_dup_drop);
+ SEQ_PRINT("Rx agg miss: %u", rx_agg_miss);
+ SEQ_PRINT("Rx ICV error: %u", rx_icv_error);
+ SEQ_PRINT("Rx FCS error: %u", rx_fcs_error);
+ SEQ_PRINT("Rx TKIP MIC error: %u", rx_tkip_mic_error);
+ SEQ_PRINT("Rx PN/IV error: %u", rx_pn_iv_error);
+#undef SEQ_PRINT
+
+ rx_mac80211 += phy->rx_stats.rx_mac80211;
+ }
+
+ seq_printf(s, "\n==========SUM==========\n");
+ seq_printf(s, "Rx to kernel: %u\n", dev->mt76.rx_kernel);
+ seq_printf(s, "Rx to mac80211: %u\n", rx_mac80211);
+
+
+ return 0;
+}
+
int mt7996_mtk_init_debugfs(struct mt7996_phy *phy, struct dentry *dir)
{
struct mt7996_dev *dev = phy->dev;
@@ -2917,6 +2957,8 @@ int mt7996_mtk_init_debugfs(struct mt7996_phy *phy, struct dentry *dir)
debugfs_create_devm_seqfile(dev->mt76.dev, "tr_info", dir,
mt7996_trinfo_read);
+ debugfs_create_devm_seqfile(dev->mt76.dev, "rx_counters", dir,
+ mt7996_rx_counters);
debugfs_create_file("txpower_level", 0600, dir, phy, &fops_txpower_level);
debugfs_create_file("txpower_info", 0600, dir, phy, &mt7996_txpower_info_fops);
debugfs_create_file("txpower_sku", 0600, dir, phy, &mt7996_txpower_sku_fops);
--
2.18.0