2023-10-25 19:10:00

by Ben Greear

[permalink] [raw]
Subject: [PATCH 10/12] wifi: mt76: mt7915: ethtool counters for driver rx path

From: Ben Greear <[email protected]>

Add some per-phy counters for rx errors in the driver.

Signed-off-by: Ben Greear <[email protected]>
---
drivers/net/wireless/mediatek/mt76/mt76.h | 11 ++++++
.../net/wireless/mediatek/mt76/mt76_connac.h | 1 +
.../wireless/mediatek/mt76/mt76_connac_mac.c | 11 +++++-
.../net/wireless/mediatek/mt76/mt7915/mac.c | 38 ++++++++++++++-----
.../net/wireless/mediatek/mt76/mt7915/main.c | 22 +++++++++++
.../net/wireless/mediatek/mt76/mt7921/mac.c | 4 +-
6 files changed, 75 insertions(+), 12 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
index 35a333ae3d84..299d6f1f9649 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -961,6 +961,17 @@ struct mt76_mib_stats {
u32 tx_amsdu[8];
u32 tx_amsdu_cnt;

+ /* rx stats from the driver */
+ unsigned long rx_d_skb; /* total skb received in rx path */
+ u32 rx_d_rxd2_amsdu_err;
+ u32 rx_d_null_channels;
+ u32 rx_d_max_len_err;
+ u32 rx_d_too_short;
+ u32 rx_d_bad_ht_rix;
+ u32 rx_d_bad_vht_rix;
+ u32 rx_d_bad_mode;
+ u32 rx_d_bad_bw;
+
/* mcu_muru_stats */
u32 dl_cck_cnt;
u32 dl_ofdm_cnt;
diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac.h b/drivers/net/wireless/mediatek/mt76/mt76_connac.h
index 8d501db26c5a..631d349ace82 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76_connac.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76_connac.h
@@ -425,6 +425,7 @@ int mt76_connac2_mac_fill_rx_rate(struct mt76_dev *dev,
struct mt76_rx_status *status,
struct ieee80211_supported_band *sband,
__le32 *rxv, u8 *mode, u8 *nss,
+ struct mt76_mib_stats *mib,
struct mt76_sta_stats *stats);
void mt76_connac2_tx_check_aggr(struct ieee80211_sta *sta, __le32 *txwi);
void mt76_connac2_txwi_free(struct mt76_dev *dev, struct mt76_txwi_cache *t,
diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c b/drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c
index d349329a8168..c56881bc2ab3 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c
@@ -1015,6 +1015,7 @@ int mt76_connac2_mac_fill_rx_rate(struct mt76_dev *dev,
struct mt76_rx_status *status,
struct ieee80211_supported_band *sband,
__le32 *rxv, u8 *mode, u8 *nss,
+ struct mt76_mib_stats *mib,
struct mt76_sta_stats *stats)
{
u32 v0, v2;
@@ -1062,15 +1063,19 @@ int mt76_connac2_mac_fill_rx_rate(struct mt76_dev *dev,
*nss = i / 8 + 1;
if (gi)
status->enc_flags |= RX_ENC_FLAG_SHORT_GI;
- if (i > 31)
+ if (i > 31) {
+ mib->rx_d_bad_ht_rix++;
return -EINVAL;
+ }
break;
case MT_PHY_TYPE_VHT:
status->encoding = RX_ENC_VHT;
if (gi)
status->enc_flags |= RX_ENC_FLAG_SHORT_GI;
- if (i > 11)
+ if (i > 11) {
+ mib->rx_d_bad_vht_rix++;
return -EINVAL;
+ }
break;
case MT_PHY_TYPE_HE_MU:
case MT_PHY_TYPE_HE_SU:
@@ -1085,6 +1090,7 @@ int mt76_connac2_mac_fill_rx_rate(struct mt76_dev *dev,
status->he_dcm = dcm;
break;
default:
+ mib->rx_d_bad_mode++;
return -EINVAL;
}
status->rate_idx = i;
@@ -1121,6 +1127,7 @@ int mt76_connac2_mac_fill_rx_rate(struct mt76_dev *dev,
stats->rx_bw_160++;
break;
default:
+ mib->rx_d_bad_bw++;
return -EINVAL;
}

diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
index 40f3320edc02..05f1b1fa4080 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
@@ -308,9 +308,12 @@ mt7915_mac_fill_rx(struct mt7915_dev *dev, struct sk_buff *skb,
__le16 fc = 0;
int idx;
struct mt76_sta_stats *stats = NULL;
+ struct mt76_mib_stats *mib = &phy->mib;

memset(status, 0, sizeof(*status));

+ mib->rx_d_skb++;
+
if ((rxd1 & MT_RXD1_NORMAL_BAND_IDX) && !phy->mt76->band_idx) {
mphy = dev->mt76.phys[MT_BAND1];
if (!mphy)
@@ -323,8 +326,10 @@ mt7915_mac_fill_rx(struct mt7915_dev *dev, struct sk_buff *skb,
if (!test_bit(MT76_STATE_RUNNING, &mphy->state))
return -EINVAL;

- if (rxd2 & MT_RXD2_NORMAL_AMSDU_ERR)
+ if (rxd2 & MT_RXD2_NORMAL_AMSDU_ERR) {
+ mib->rx_d_rxd2_amsdu_err++;
return -EINVAL;
+ }

hdr_trans = rxd2 & MT_RXD2_NORMAL_HDR_TRANS;
if (hdr_trans && (rxd1 & MT_RXD1_NORMAL_CM))
@@ -357,8 +362,10 @@ mt7915_mac_fill_rx(struct mt7915_dev *dev, struct sk_buff *skb,
else
sband = &mphy->sband_2g.sband;

- if (!sband->channels)
+ if (!sband->channels) {
+ mib->rx_d_null_channels++;
return -EINVAL;
+ }

if ((rxd0 & csum_mask) == csum_mask &&
!(csum_status & (BIT(0) | BIT(2) | BIT(3))))
@@ -379,8 +386,10 @@ mt7915_mac_fill_rx(struct mt7915_dev *dev, struct sk_buff *skb,

remove_pad = FIELD_GET(MT_RXD2_NORMAL_HDR_OFFSET, rxd2);

- if (rxd2 & MT_RXD2_NORMAL_MAX_LEN_ERROR)
+ if (rxd2 & MT_RXD2_NORMAL_MAX_LEN_ERROR) {
+ mib->rx_d_max_len_err++;
return -EINVAL;
+ }

rxd += 6;
if (rxd1 & MT_RXD1_NORMAL_GROUP_4) {
@@ -392,8 +401,10 @@ mt7915_mac_fill_rx(struct mt7915_dev *dev, struct sk_buff *skb,
seq_ctrl = FIELD_GET(MT_RXD8_SEQ_CTRL, v2);

rxd += 4;
- if ((u8 *)rxd - skb->data >= skb->len)
+ if ((u8 *)rxd - skb->data >= skb->len) {
+ mib->rx_d_too_short++;
return -EINVAL;
+ }
}

if (rxd1 & MT_RXD1_NORMAL_GROUP_1) {
@@ -423,8 +434,10 @@ mt7915_mac_fill_rx(struct mt7915_dev *dev, struct sk_buff *skb,
}
}
rxd += 4;
- if ((u8 *)rxd - skb->data >= skb->len)
+ if ((u8 *)rxd - skb->data >= skb->len) {
+ mib->rx_d_too_short++;
return -EINVAL;
+ }
}

if (rxd1 & MT_RXD1_NORMAL_GROUP_2) {
@@ -445,8 +458,10 @@ mt7915_mac_fill_rx(struct mt7915_dev *dev, struct sk_buff *skb,
}

rxd += 2;
- if ((u8 *)rxd - skb->data >= skb->len)
+ if ((u8 *)rxd - skb->data >= skb->len) {
+ mib->rx_d_too_short++;
return -EINVAL;
+ }
}

/* RXD Group 3 - P-RXV */
@@ -458,8 +473,10 @@ mt7915_mac_fill_rx(struct mt7915_dev *dev, struct sk_buff *skb,

rxv = rxd;
rxd += 2;
- if ((u8 *)rxd - skb->data >= skb->len)
+ if ((u8 *)rxd - skb->data >= skb->len) {
+ mib->rx_d_too_short++;
return -EINVAL;
+ }

v0 = le32_to_cpu(rxv[0]);
v1 = le32_to_cpu(rxv[1]);
@@ -479,14 +496,17 @@ mt7915_mac_fill_rx(struct mt7915_dev *dev, struct sk_buff *skb,
/* RXD Group 5 - C-RXV */
if (rxd1 & MT_RXD1_NORMAL_GROUP_5) {
rxd += 18;
- if ((u8 *)rxd - skb->data >= skb->len)
+ if ((u8 *)rxd - skb->data >= skb->len) {
+ mib->rx_d_too_short++;
return -EINVAL;
+ }
}

if (!is_mt7915(&dev->mt76) || (rxd1 & MT_RXD1_NORMAL_GROUP_5)) {
ret = mt76_connac2_mac_fill_rx_rate(&dev->mt76, status,
sband, rxv, &mode,
- &nss, stats);
+ &nss, mib,
+ stats);
if (ret < 0)
return ret;
} else {
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/main.c b/drivers/net/wireless/mediatek/mt76/mt7915/main.c
index 05b633932e16..7fb60178939b 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/main.c
@@ -1357,6 +1357,17 @@ static const char mt7915_gstrings_stats[][ETH_GSTRING_LEN] = {
"ul_hetrig_3mu_cnt",
"ul_hetrig_4mu_cnt",

+ /* driver rx counters */
+ "d_rx_skb",
+ "d_rx_rxd2_amsdu_err",
+ "d_rx_null_channels",
+ "d_rx_max_len_err",
+ "d_rx_too_short",
+ "d_rx_bad_ht_rix",
+ "d_rx_bad_vht_rix",
+ "d_rx_bad_mode",
+ "d_rx_bad_bw",
+
/* per vif counters */
"v_tx_mpdu_attempts", /* counting any retries */
"v_tx_mpdu_fail", /* frames that failed even after retry */
@@ -1567,6 +1578,17 @@ void mt7915_get_et_stats(struct ieee80211_hw *hw,
data[ei++] = mib->ul_hetrig_3mu_cnt;
data[ei++] = mib->ul_hetrig_4mu_cnt;

+ /* rx stats from driver */
+ data[ei++] = mib->rx_d_skb;
+ data[ei++] = mib->rx_d_rxd2_amsdu_err;
+ data[ei++] = mib->rx_d_null_channels;
+ data[ei++] = mib->rx_d_max_len_err;
+ data[ei++] = mib->rx_d_too_short;
+ data[ei++] = mib->rx_d_bad_ht_rix;
+ data[ei++] = mib->rx_d_bad_vht_rix;
+ data[ei++] = mib->rx_d_bad_mode;
+ data[ei++] = mib->rx_d_bad_bw;
+
/* Add values for all stations owned by this vif */
wi.initial_stat_idx = ei;
ieee80211_iterate_stations_atomic(hw, mt7915_ethtool_worker, &wi);
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
index 9f2c8a3a4202..26defc8930ef 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
@@ -190,6 +190,7 @@ mt7921_mac_fill_rx(struct mt792x_dev *dev, struct sk_buff *skb)
u8 mode = 0;
int i, idx;
struct mt76_sta_stats *stats = NULL;
+ struct mt76_mib_stats *mib = &phy->mib;

memset(status, 0, sizeof(*status));

@@ -349,7 +350,8 @@ mt7921_mac_fill_rx(struct mt792x_dev *dev, struct sk_buff *skb)
status->enc_flags |= RX_ENC_FLAG_LDPC;

ret = mt76_connac2_mac_fill_rx_rate(&dev->mt76, status, sband,
- rxv, &mode, &nss, stats);
+ rxv, &mode, &nss,
+ mib, stats);
if (ret < 0)
return ret;

--
2.40.0


2023-10-25 19:10:05

by Ben Greear

[permalink] [raw]
Subject: [PATCH 12/12] wifi: mt76: mt7915: add rx-ppdu-size-out-of-range ethtool counter

From: Ben Greear <[email protected]>

Support this additional MIB counter, it shares register with
the rx-fifo-overflow counter.

Signed-off-by: Ben Greear <[email protected]>
---
drivers/net/wireless/mediatek/mt76/mt76.h | 1 +
drivers/net/wireless/mediatek/mt76/mt7915/mac.c | 1 +
drivers/net/wireless/mediatek/mt76/mt7915/main.c | 4 +++-
drivers/net/wireless/mediatek/mt76/mt7915/regs.h | 1 +
4 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
index 9b5c1ee7951d..03ec0eedaa8f 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -944,6 +944,7 @@ struct mt76_mib_stats {

/* rx stats */
u32 rx_fifo_full_cnt;
+ u32 rx_oor_cnt;
u32 channel_idle_cnt;
u32 primary_cca_busy_time;
u32 secondary_cca_busy_time;
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
index f6d8e08d7083..d6ec34dff090 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
@@ -1829,6 +1829,7 @@ void mt7915_mac_update_stats(struct mt7915_phy *phy)

cnt = mt76_rr(dev, MT_MIB_SDR4(band));
mib->rx_fifo_full_cnt += FIELD_GET(MT_MIB_SDR4_RX_FIFO_FULL_MASK, cnt);
+ mib->rx_oor_cnt += FIELD_GET(MT_MIB_SDR4_RX_OOR_MASK, cnt);

cnt = mt76_rr(dev, MT_MIB_SDR5(band));
mib->rx_mpdu_cnt += cnt;
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/main.c b/drivers/net/wireless/mediatek/mt76/mt7915/main.c
index e9b3b247c0d5..e9d3a47e7747 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/main.c
@@ -1309,6 +1309,7 @@ static const char mt7915_gstrings_stats[][ETH_GSTRING_LEN] = {

/* rx counters */
"rx_fifo_full_cnt",
+ "rx_oor_cnt", /* rx ppdu length is bad */
"rx_mpdu_cnt",
"channel_idle_cnt",
"primary_cca_busy_time",
@@ -1537,7 +1538,8 @@ void mt7915_get_et_stats(struct ieee80211_hw *hw,
data[ei++] = mib->tx_amsdu[i];

/* rx counters */
- data[ei++] = mib->rx_fifo_full_cnt;
+ data[ei++] = mib->rx_fifo_full_cnt; /* group-5 might exacerbate this */
+ data[ei++] = mib->rx_oor_cnt;
data[ei++] = mib->rx_mpdu_cnt;
data[ei++] = mib->channel_idle_cnt;
data[ei++] = mib->primary_cca_busy_time;
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/regs.h b/drivers/net/wireless/mediatek/mt76/mt7915/regs.h
index 89ac8e6707b8..a3070f07177b 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/regs.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/regs.h
@@ -313,6 +313,7 @@ enum offs_rev {

#define MT_MIB_SDR4(_band) MT_WF_MIB(_band, __OFFS(MIB_SDR4))
#define MT_MIB_SDR4_RX_FIFO_FULL_MASK GENMASK(15, 0)
+#define MT_MIB_SDR4_RX_OOR_MASK GENMASK(23, 16)

/* rx mpdu counter, full 32 bits */
#define MT_MIB_SDR5(_band) MT_WF_MIB(_band, __OFFS(MIB_SDR5))
--
2.40.0