2021-07-23 15:47:05

by Ben Greear

[permalink] [raw]
Subject: [PATCH v4 1/8] mt76 - mt7915: Add ethtool stats support.

From: Ben Greear <[email protected]>

This exposes some tx-path stats to the ethtool API, so that
ethtool -S wlanX provides some more useful info.

Signed-off-by: Ben Greear <[email protected]>
---

v4: move ethtool code to main.c
Re-work the 2/8 patch per review.
Did not try to refactor the station walk per comments on 3/8, I saw
no clean way to do that.

.../net/wireless/mediatek/mt76/mt7915/main.c | 136 ++++++++++++++++++
1 file changed, 136 insertions(+)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/main.c b/drivers/net/wireless/mediatek/mt76/mt7915/main.c
index 48b5e2051bad..d0288fe2abdf 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/main.c
@@ -1028,6 +1028,139 @@ static void mt7915_sta_set_decap_offload(struct ieee80211_hw *hw,
mt7915_mcu_sta_update_hdr_trans(dev, vif, sta);
}

+static const char mt7915_gstrings_stats[][ETH_GSTRING_LEN] = {
+ "tx_ampdu_len:0-1",
+ "tx_ampdu_len:2-10",
+ "tx_ampdu_len:11-19",
+ "tx_ampdu_len:20-28",
+ "tx_ampdu_len:29-37",
+ "tx_ampdu_len:38-46",
+ "tx_ampdu_len:47-55",
+ "tx_ampdu_len:56-79",
+ "tx_ampdu_len:80-103",
+ "tx_ampdu_len:104-127",
+ "tx_ampdu_len:128-151",
+ "tx_ampdu_len:152-175",
+ "tx_ampdu_len:176-199",
+ "tx_ampdu_len:200-223",
+ "tx_ampdu_len:224-247",
+ "ba_miss_count",
+ "tx_beamformer_ppdu_iBF",
+ "tx_beamformer_ppdu_eBF",
+ "tx_beamformer_rx_feedback_all",
+ "tx_beamformer_rx_feedback_he",
+ "tx_beamformer_rx_feedback_vht",
+ "tx_beamformer_rx_feedback_ht",
+ "tx_beamformer_rx_feedback_bw", /* zero based idx: 20, 40, 80, 160 */
+ "tx_beamformer_rx_feedback_nc",
+ "tx_beamformer_rx_feedback_nr",
+ "tx_beamformee_ok_feedback_pkts",
+ "tx_beamformee_feedback_trig",
+ "tx_mu_beamforming",
+ "tx_mu_mpdu",
+ "tx_mu_successful_mpdu",
+ "tx_su_successful_mpdu",
+ "tx_msdu_pack_1",
+ "tx_msdu_pack_2",
+ "tx_msdu_pack_3",
+ "tx_msdu_pack_4",
+ "tx_msdu_pack_5",
+ "tx_msdu_pack_6",
+ "tx_msdu_pack_7",
+ "tx_msdu_pack_8",
+};
+
+#define MT7915_SSTATS_LEN ARRAY_SIZE(mt7915_gstrings_stats)
+
+/* Ethtool related API */
+void mt7915_get_et_strings(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ u32 sset, u8 *data)
+{
+ if (sset == ETH_SS_STATS)
+ memcpy(data, *mt7915_gstrings_stats,
+ sizeof(mt7915_gstrings_stats));
+}
+
+int mt7915_get_et_sset_count(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif, int sset)
+{
+ if (sset == ETH_SS_STATS)
+ return MT7915_SSTATS_LEN;
+
+ return 0;
+}
+
+void mt7915_get_et_stats(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ethtool_stats *stats, u64 *data)
+{
+ struct mt7915_dev *dev = mt7915_hw_dev(hw);
+ struct mt7915_phy *phy = mt7915_hw_phy(hw);
+
+ /* TODO: These are mostly dev-wide stats at this point.
+ * Get some per-vif stats?
+ */
+
+ /* See mt7915_ampdu_stat_read_phy, etc */
+ bool ext_phy = phy != &dev->phy;
+ int i, n, cnt;
+ int ei = 0;
+
+ if (!phy)
+ return;
+
+ /* Tx ampdu stat */
+ n = ext_phy ? ARRAY_SIZE(dev->mt76.aggr_stats) / 2 : 0;
+ for (i = 0; i < 15 /*ARRAY_SIZE(bound)*/; i++)
+ data[ei++] = dev->mt76.aggr_stats[i + n];
+
+ data[ei++] = phy->mib.ba_miss_cnt;
+
+ /* Tx Beamformer monitor */
+ cnt = mt76_rr(dev, MT_ETBF_TX_APP_CNT(ext_phy));
+ data[ei++] = FIELD_GET(MT_ETBF_TX_IBF_CNT, cnt);
+ data[ei++] = FIELD_GET(MT_ETBF_TX_EBF_CNT, cnt);
+
+ /* Tx Beamformer Rx feedback monitor */
+ cnt = mt76_rr(dev, MT_ETBF_RX_FB_CNT(ext_phy));
+ data[ei++] = FIELD_GET(MT_ETBF_RX_FB_ALL, cnt);
+ data[ei++] = FIELD_GET(MT_ETBF_RX_FB_HE, cnt);
+ data[ei++] = FIELD_GET(MT_ETBF_RX_FB_VHT, cnt);
+ data[ei++] = FIELD_GET(MT_ETBF_RX_FB_HT, cnt);
+
+ cnt = mt76_rr(dev, MT_ETBF_RX_FB_CONT(ext_phy));
+ data[ei++] = FIELD_GET(MT_ETBF_RX_FB_BW, cnt);
+ data[ei++] = FIELD_GET(MT_ETBF_RX_FB_NC, cnt);
+ data[ei++] = FIELD_GET(MT_ETBF_RX_FB_NR, cnt);
+
+ /* Tx Beamformee Rx NDPA & Tx feedback report */
+ cnt = mt76_rr(dev, MT_ETBF_TX_NDP_BFRP(ext_phy));
+ data[ei++] = FIELD_GET(MT_ETBF_TX_FB_CPL, cnt);
+ data[ei++] = FIELD_GET(MT_ETBF_TX_FB_TRI, cnt);
+
+ /* Tx SU & MU counters */
+ cnt = mt76_rr(dev, MT_MIB_SDR34(ext_phy));
+ data[ei++] = FIELD_GET(MT_MIB_MU_BF_TX_CNT, cnt);
+
+ cnt = mt76_rr(dev, MT_MIB_DR8(ext_phy));
+ data[ei++] = cnt;
+
+ cnt = mt76_rr(dev, MT_MIB_DR9(ext_phy));
+ data[ei++] = cnt; /* MU MPDU SUccessful */
+
+ cnt = mt76_rr(dev, MT_MIB_DR11(ext_phy));
+ data[ei++] = cnt; /* SU MPDU successful */
+
+ /* TODO: External phy too?? */
+
+ /* Tx amsdu info (pack-count histogram) */
+ for (i = 0; i < 8; i++)
+ data[ei++] = mt76_rr(dev, MT_PLE_AMSDU_PACK_MSDU_CNT(i));
+
+ WARN_ON(ei != MT7915_SSTATS_LEN);
+}
+
const struct ieee80211_ops mt7915_ops = {
.tx = mt7915_tx,
.start = mt7915_start,
@@ -1052,6 +1185,9 @@ const struct ieee80211_ops mt7915_ops = {
.get_txpower = mt76_get_txpower,
.channel_switch_beacon = mt7915_channel_switch_beacon,
.get_stats = mt7915_get_stats,
+ .get_et_sset_count = mt7915_get_et_sset_count,
+ .get_et_stats = mt7915_get_et_stats,
+ .get_et_strings = mt7915_get_et_strings,
.get_tsf = mt7915_get_tsf,
.set_tsf = mt7915_set_tsf,
.offset_tsf = mt7915_offset_tsf,
--
2.20.1


2021-07-23 15:47:12

by Ben Greear

[permalink] [raw]
Subject: [PATCH v4 2/8] mt76 - mt7915: Add tx stats gathered from tx-status callbacks.

From: Ben Greear <[email protected]>

Add tx-mode (ofdma, ht, vht, HE) histogram,
tx-ru-idx histogram, and tx-bandwidth histogram.
Also add tx attempts and tx success counters.

All of this is per-station.

Signed-off-by: Ben Greear <[email protected]>
---
drivers/net/wireless/mediatek/mt76/mt76.h | 1 +
.../net/wireless/mediatek/mt76/mt7915/mac.c | 36 +++++++++++++++----
.../wireless/mediatek/mt76/mt7915/mt7915.h | 14 ++++++++
3 files changed, 44 insertions(+), 7 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
index b41faedee001..436bf2b8e2cd 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -755,6 +755,7 @@ enum mt76_phy_type {
MT_PHY_TYPE_HE_EXT_SU,
MT_PHY_TYPE_HE_TB,
MT_PHY_TYPE_HE_MU,
+ MT_PHY_TYPE_HE_LAST, /* keep last */
};

#define CCK_RATE(_idx, _rate) { \
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
index f1574538315d..6f445999e516 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
@@ -1304,7 +1304,7 @@ mt7915_mac_tx_free(struct mt7915_dev *dev, struct sk_buff *skb)

static bool
mt7915_mac_add_txs_skb(struct mt7915_dev *dev, struct mt76_wcid *wcid, int pid,
- __le32 *txs_data)
+ __le32 *txs_data, struct mt7915_sta_stats *stats)
{
struct ieee80211_supported_band *sband;
struct mt76_dev *mdev = &dev->mt76;
@@ -1314,7 +1314,7 @@ mt7915_mac_add_txs_skb(struct mt7915_dev *dev, struct mt76_wcid *wcid, int pid,
struct rate_info rate = {};
struct sk_buff *skb;
bool cck = false;
- u32 txrate, txs;
+ u32 txrate, txs, txs5, txs6, txs7, mode;

mt76_tx_status_lock(mdev, &list);
skb = mt76_tx_status_skb_get(mdev, wcid, pid, &list);
@@ -1322,6 +1322,9 @@ mt7915_mac_add_txs_skb(struct mt7915_dev *dev, struct mt76_wcid *wcid, int pid,
goto out;

txs = le32_to_cpu(txs_data[0]);
+ txs5 = le32_to_cpu(txs_data[5]);
+ txs6 = le32_to_cpu(txs_data[6]);
+ txs7 = le32_to_cpu(txs_data[7]);

info = IEEE80211_SKB_CB(skb);
if (!(txs & MT_TXS0_ACK_ERROR_MASK))
@@ -1333,15 +1336,27 @@ mt7915_mac_add_txs_skb(struct mt7915_dev *dev, struct mt76_wcid *wcid, int pid,

info->status.rates[0].idx = -1;

- if (!wcid->sta)
- goto out;
+ stats->tx_mpdu_attempts += FIELD_GET(MT_TXS5_F1_MPDU_TX_COUNT, txs5);
+ stats->tx_mpdu_fail += FIELD_GET(MT_TXS6_F1_MPDU_FAIL_COUNT, txs6);
+ stats->tx_mpdu_retry += FIELD_GET(MT_TXS7_F1_MPDU_RETRY_COUNT, txs7);

txrate = FIELD_GET(MT_TXS0_TX_RATE, txs);

rate.mcs = FIELD_GET(MT_TX_RATE_IDX, txrate);
rate.nss = FIELD_GET(MT_TX_RATE_NSS, txrate) + 1;

- switch (FIELD_GET(MT_TX_RATE_MODE, txrate)) {
+ stats->tx_nss[rate.nss - 1]++;
+ /* It appears that rate.mcs even for HT may be small, considering in HT
+ * code below it is multiplied... but not certain on that,
+ * so code safely.
+ */
+ if (rate.mcs >= ARRAY_SIZE(stats->tx_mcs))
+ stats->tx_mcs[ARRAY_SIZE(stats->tx_mcs) - 1]++;
+ else
+ stats->tx_mcs[rate.mcs]++;
+
+ mode = FIELD_GET(MT_TX_RATE_MODE, txrate);
+ switch (mode) {
case MT_PHY_TYPE_CCK:
cck = true;
fallthrough;
@@ -1389,18 +1404,24 @@ mt7915_mac_add_txs_skb(struct mt7915_dev *dev, struct mt76_wcid *wcid, int pid,
goto out;
}

+ stats->tx_mode[mode]++;
+
switch (FIELD_GET(MT_TXS0_BW, txs)) {
case IEEE80211_STA_RX_BW_160:
rate.bw = RATE_INFO_BW_160;
+ stats->tx_bw[3]++;
break;
case IEEE80211_STA_RX_BW_80:
rate.bw = RATE_INFO_BW_80;
+ stats->tx_bw[2]++;
break;
case IEEE80211_STA_RX_BW_40:
rate.bw = RATE_INFO_BW_40;
+ stats->tx_bw[1]++;
break;
default:
rate.bw = RATE_INFO_BW_20;
+ stats->tx_bw[0]++;
break;
}
wcid->rate = rate;
@@ -1443,12 +1464,13 @@ static void mt7915_mac_add_txs(struct mt7915_dev *dev, void *data)
if (!wcid)
goto out;

- mt7915_mac_add_txs_skb(dev, wcid, pid, txs_data);
+ msta = container_of(wcid, struct mt7915_sta, wcid);
+
+ mt7915_mac_add_txs_skb(dev, wcid, pid, txs_data, &msta->stats);

if (!wcid->sta)
goto out;

- msta = container_of(wcid, struct mt7915_sta, wcid);
spin_lock_bh(&dev->sta_poll_lock);
if (list_empty(&msta->poll_list))
list_add_tail(&msta->poll_list, &dev->sta_poll_list);
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
index 33be449309e0..a8617ba69a21 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
@@ -64,6 +64,16 @@ enum mt7915_rxq_id {
MT7915_RXQ_MCU_WA_EXT,
};

+struct mt7915_sta_stats {
+ unsigned long tx_mpdu_attempts;
+ unsigned long tx_mpdu_fail;
+ unsigned long tx_mpdu_retry;
+ unsigned long tx_mode[MT_PHY_TYPE_HE_LAST]; /* See mt76_phy_type */
+ unsigned long tx_bw[4]; /* 20, 40, 80, 160 */
+ unsigned long tx_nss[4]; /* 1, 2, 3, 4 */
+ unsigned long tx_mcs[16]; /* mcs idx */
+};
+
struct mt7915_sta_key_conf {
s8 keyidx;
u8 key[16];
@@ -82,8 +92,11 @@ struct mt7915_sta {
unsigned long jiffies;
unsigned long ampdu_state;

+ struct mt7915_sta_stats stats;
+
struct mt7915_sta_key_conf bip;
};
+
struct mt7915_vif {
u16 idx;
u8 omac_idx;
@@ -103,6 +116,7 @@ struct mib_stats {
u32 rts_cnt;
u32 rts_retries_cnt;
u32 ba_miss_cnt;
+ /* Add more stats here, updated from mac_update_stats */
};

struct mt7915_hif {
--
2.20.1

2021-07-23 15:47:18

by Ben Greear

[permalink] [raw]
Subject: [PATCH v4 4/8] mt76 - mt7915: Add tx mu/su counters to mib

From: Ben Greear <[email protected]>

These counters are clear-on-read, so we need to accumulate
them in the update_stats poll logic, and read the accumulated
values instead of directly doing register reads when reporting
to debugfs and ethtool stats.

Signed-off-by: Ben Greear <[email protected]>
---
.../net/wireless/mediatek/mt76/mt7915/debugfs.c | 17 ++++++++---------
drivers/net/wireless/mediatek/mt76/mt7915/mac.c | 13 ++++++++++++-
.../net/wireless/mediatek/mt76/mt7915/main.c | 16 +++++-----------
.../net/wireless/mediatek/mt76/mt7915/mt7915.h | 4 ++++
4 files changed, 29 insertions(+), 21 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c b/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c
index 1a48b09d0cb7..35248d182728 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c
@@ -152,6 +152,7 @@ mt7915_txbf_stat_read_phy(struct mt7915_phy *phy, struct seq_file *s)
"BW20", "BW40", "BW80", "BW160"
};
int cnt;
+ struct mib_stats *mib = &phy->mib;

if (!phy)
return;
@@ -187,15 +188,13 @@ mt7915_txbf_stat_read_phy(struct mt7915_phy *phy, struct seq_file *s)
FIELD_GET(MT_ETBF_TX_FB_TRI, cnt));

/* Tx SU & MU counters */
- cnt = mt76_rr(dev, MT_MIB_SDR34(ext_phy));
- seq_printf(s, "Tx multi-user Beamforming counts: %ld\n",
- FIELD_GET(MT_MIB_MU_BF_TX_CNT, cnt));
- cnt = mt76_rr(dev, MT_MIB_DR8(ext_phy));
- seq_printf(s, "Tx multi-user MPDU counts: %d\n", cnt);
- cnt = mt76_rr(dev, MT_MIB_DR9(ext_phy));
- seq_printf(s, "Tx multi-user successful MPDU counts: %d\n", cnt);
- cnt = mt76_rr(dev, MT_MIB_DR11(ext_phy));
- seq_printf(s, "Tx single-user successful MPDU counts: %d\n", cnt);
+ seq_printf(s, "Tx multi-user Beamforming counts: %d\n",
+ mib->tx_bf_cnt);
+ seq_printf(s, "Tx multi-user MPDU counts: %d\n", mib->tx_mu_mpdu_cnt);
+ seq_printf(s, "Tx multi-user successful MPDU counts: %d\n",
+ mib->tx_mu_acked_mpdu_cnt);
+ seq_printf(s, "Tx single-user successful MPDU counts: %d\n",
+ mib->tx_su_acked_mpdu_cnt);

seq_puts(s, "\n");
}
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
index 6f445999e516..064d754e0565 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
@@ -1890,10 +1890,21 @@ mt7915_mac_update_stats(struct mt7915_phy *phy)
struct mt7915_dev *dev = phy->dev;
struct mib_stats *mib = &phy->mib;
bool ext_phy = phy != &dev->phy;
- int i, aggr0, aggr1;
+ int i, aggr0, aggr1, cnt;

mib->fcs_err_cnt += mt76_get_field(dev, MT_MIB_SDR3(ext_phy),
MT_MIB_SDR3_FCS_ERR_MASK);
+ cnt = mt76_rr(dev, MT_MIB_SDR34(ext_phy));
+ mib->tx_bf_cnt += FIELD_GET(MT_MIB_MU_BF_TX_CNT, cnt);
+
+ cnt = mt76_rr(dev, MT_MIB_DR8(ext_phy));
+ mib->tx_mu_mpdu_cnt += cnt;
+
+ cnt = mt76_rr(dev, MT_MIB_DR9(ext_phy));
+ mib->tx_mu_acked_mpdu_cnt += cnt;
+
+ cnt = mt76_rr(dev, MT_MIB_DR11(ext_phy));
+ mib->tx_su_acked_mpdu_cnt += cnt;

aggr0 = ext_phy ? ARRAY_SIZE(dev->mt76.aggr_stats) / 2 : 0;
for (i = 0, aggr1 = aggr0 + 4; i < 4; i++) {
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/main.c b/drivers/net/wireless/mediatek/mt76/mt7915/main.c
index de083008663e..be6444650afe 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/main.c
@@ -1131,6 +1131,7 @@ void mt7915_get_et_stats(struct ieee80211_hw *hw,
struct mt7915_sta *msta;
struct mt7915_sta_stats *mstats;
bool found_sta = false;
+ struct mib_stats *mib = &phy->mib;

/* See mt7915_ampdu_stat_read_phy, etc */
bool ext_phy = phy != &dev->phy;
@@ -1170,17 +1171,10 @@ void mt7915_get_et_stats(struct ieee80211_hw *hw,
data[ei++] = FIELD_GET(MT_ETBF_TX_FB_TRI, cnt);

/* Tx SU & MU counters */
- cnt = mt76_rr(dev, MT_MIB_SDR34(ext_phy));
- data[ei++] = FIELD_GET(MT_MIB_MU_BF_TX_CNT, cnt);
-
- cnt = mt76_rr(dev, MT_MIB_DR8(ext_phy));
- data[ei++] = cnt;
-
- cnt = mt76_rr(dev, MT_MIB_DR9(ext_phy));
- data[ei++] = cnt; /* MU MPDU SUccessful */
-
- cnt = mt76_rr(dev, MT_MIB_DR11(ext_phy));
- data[ei++] = cnt; /* SU MPDU successful */
+ data[ei++] = mib->tx_bf_cnt;
+ data[ei++] = mib->tx_mu_mpdu_cnt;
+ data[ei++] = mib->tx_mu_acked_mpdu_cnt;
+ data[ei++] = mib->tx_su_acked_mpdu_cnt;

/* TODO: External phy too?? */

diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
index a8617ba69a21..26f2befc46dd 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
@@ -116,6 +116,10 @@ struct mib_stats {
u32 rts_cnt;
u32 rts_retries_cnt;
u32 ba_miss_cnt;
+ u32 tx_bf_cnt;
+ u32 tx_mu_mpdu_cnt;
+ u32 tx_mu_acked_mpdu_cnt;
+ u32 tx_su_acked_mpdu_cnt;
/* Add more stats here, updated from mac_update_stats */
};

--
2.20.1

2021-07-23 15:47:24

by Ben Greear

[permalink] [raw]
Subject: [PATCH v4 5/8] mt76 - mt7915: Move more tx-bf stats to mib.

From: Ben Greear <[email protected]>

These are clear-on-read, so accumulate them in the update_stats
polling method, then access them via the mib structure
when reading them from debugfs/ethtool.

Signed-off-by: Ben Greear <[email protected]>
---
.../wireless/mediatek/mt76/mt7915/debugfs.c | 44 +++++++++----------
.../net/wireless/mediatek/mt76/mt7915/mac.c | 19 ++++++++
.../net/wireless/mediatek/mt76/mt7915/main.c | 28 +++++-------
.../wireless/mediatek/mt76/mt7915/mt7915.h | 15 +++++++
4 files changed, 66 insertions(+), 40 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c b/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c
index 35248d182728..91664ac63a8d 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c
@@ -146,46 +146,42 @@ mt7915_ampdu_stat_read_phy(struct mt7915_phy *phy,
static void
mt7915_txbf_stat_read_phy(struct mt7915_phy *phy, struct seq_file *s)
{
- struct mt7915_dev *dev = s->private;
- bool ext_phy = phy != &dev->phy;
static const char * const bw[] = {
"BW20", "BW40", "BW80", "BW160"
};
- int cnt;
- struct mib_stats *mib = &phy->mib;
+ struct mib_stats *mib;

if (!phy)
return;

+ mib = &phy->mib;
+
/* Tx Beamformer monitor */
seq_puts(s, "\nTx Beamformer applied PPDU counts: ");

- cnt = mt76_rr(dev, MT_ETBF_TX_APP_CNT(ext_phy));
- seq_printf(s, "iBF: %ld, eBF: %ld\n",
- FIELD_GET(MT_ETBF_TX_IBF_CNT, cnt),
- FIELD_GET(MT_ETBF_TX_EBF_CNT, cnt));
+ seq_printf(s, "iBF: %d, eBF: %d\n",
+ mib->tx_bf_ibf_ppdu_cnt,
+ mib->tx_bf_ebf_ppdu_cnt);

/* Tx Beamformer Rx feedback monitor */
seq_puts(s, "Tx Beamformer Rx feedback statistics: ");

- cnt = mt76_rr(dev, MT_ETBF_RX_FB_CNT(ext_phy));
- seq_printf(s, "All: %ld, HE: %ld, VHT: %ld, HT: %ld, ",
- FIELD_GET(MT_ETBF_RX_FB_ALL, cnt),
- FIELD_GET(MT_ETBF_RX_FB_HE, cnt),
- FIELD_GET(MT_ETBF_RX_FB_VHT, cnt),
- FIELD_GET(MT_ETBF_RX_FB_HT, cnt));
- cnt = mt76_rr(dev, MT_ETBF_RX_FB_CONT(ext_phy));
- seq_printf(s, "%s, NC: %ld, NR: %ld\n",
- bw[FIELD_GET(MT_ETBF_RX_FB_BW, cnt)],
- FIELD_GET(MT_ETBF_RX_FB_NC, cnt),
- FIELD_GET(MT_ETBF_RX_FB_NR, cnt));
+ seq_printf(s, "All: %d, HE: %d, VHT: %d, HT: %d, ",
+ mib->tx_bf_rx_fb_all_cnt,
+ mib->tx_bf_rx_fb_he_cnt,
+ mib->tx_bf_rx_fb_vht_cnt,
+ mib->tx_bf_rx_fb_ht_cnt);
+
+ seq_printf(s, "%s, NC: %d, NR: %d\n",
+ bw[mib->tx_bf_rx_fb_bw],
+ mib->tx_bf_rx_fb_nc_cnt,
+ mib->tx_bf_rx_fb_nr_cnt);

/* Tx Beamformee Rx NDPA & Tx feedback report */
- cnt = mt76_rr(dev, MT_ETBF_TX_NDP_BFRP(ext_phy));
- seq_printf(s, "Tx Beamformee successful feedback frames: %ld\n",
- FIELD_GET(MT_ETBF_TX_FB_CPL, cnt));
- seq_printf(s, "Tx Beamformee feedback triggered counts: %ld\n",
- FIELD_GET(MT_ETBF_TX_FB_TRI, cnt));
+ seq_printf(s, "Tx Beamformee successful feedback frames: %d\n",
+ mib->tx_bf_fb_cpl_cnt);
+ seq_printf(s, "Tx Beamformee feedback triggered counts: %d\n",
+ mib->tx_bf_fb_trig_cnt);

/* Tx SU & MU counters */
seq_printf(s, "Tx multi-user Beamforming counts: %d\n",
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
index 064d754e0565..c395600b378a 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
@@ -1906,6 +1906,25 @@ mt7915_mac_update_stats(struct mt7915_phy *phy)
cnt = mt76_rr(dev, MT_MIB_DR11(ext_phy));
mib->tx_su_acked_mpdu_cnt += cnt;

+ cnt = mt76_rr(dev, MT_ETBF_TX_APP_CNT(ext_phy));
+ mib->tx_bf_ibf_ppdu_cnt += FIELD_GET(MT_ETBF_TX_IBF_CNT, cnt);
+ mib->tx_bf_ebf_ppdu_cnt += FIELD_GET(MT_ETBF_TX_EBF_CNT, cnt);
+
+ cnt = mt76_rr(dev, MT_ETBF_RX_FB_CNT(ext_phy));
+ mib->tx_bf_rx_fb_all_cnt += FIELD_GET(MT_ETBF_RX_FB_ALL, cnt);
+ mib->tx_bf_rx_fb_he_cnt += FIELD_GET(MT_ETBF_RX_FB_HE, cnt);
+ mib->tx_bf_rx_fb_vht_cnt += FIELD_GET(MT_ETBF_RX_FB_VHT, cnt);
+ mib->tx_bf_rx_fb_ht_cnt += FIELD_GET(MT_ETBF_RX_FB_HT, cnt);
+
+ cnt = mt76_rr(dev, MT_ETBF_RX_FB_CONT(ext_phy));
+ mib->tx_bf_rx_fb_bw = FIELD_GET(MT_ETBF_RX_FB_BW, cnt);
+ mib->tx_bf_rx_fb_nc_cnt += FIELD_GET(MT_ETBF_RX_FB_NC, cnt);
+ mib->tx_bf_rx_fb_nr_cnt += FIELD_GET(MT_ETBF_RX_FB_NR, cnt);
+
+ cnt = mt76_rr(dev, MT_ETBF_TX_NDP_BFRP(ext_phy));
+ mib->tx_bf_fb_cpl_cnt += FIELD_GET(MT_ETBF_TX_FB_CPL, cnt);
+ mib->tx_bf_fb_trig_cnt += FIELD_GET(MT_ETBF_TX_FB_TRI, cnt);
+
aggr0 = ext_phy ? ARRAY_SIZE(dev->mt76.aggr_stats) / 2 : 0;
for (i = 0, aggr1 = aggr0 + 4; i < 4; i++) {
u32 val;
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/main.c b/drivers/net/wireless/mediatek/mt76/mt7915/main.c
index be6444650afe..885e35bf0fe8 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/main.c
@@ -1135,7 +1135,7 @@ void mt7915_get_et_stats(struct ieee80211_hw *hw,

/* See mt7915_ampdu_stat_read_phy, etc */
bool ext_phy = phy != &dev->phy;
- int i, j, n, cnt, next_ei;
+ int i, j, n, next_ei;
int ei = 0;

if (!phy)
@@ -1149,26 +1149,22 @@ void mt7915_get_et_stats(struct ieee80211_hw *hw,
data[ei++] = phy->mib.ba_miss_cnt;

/* Tx Beamformer monitor */
- cnt = mt76_rr(dev, MT_ETBF_TX_APP_CNT(ext_phy));
- data[ei++] = FIELD_GET(MT_ETBF_TX_IBF_CNT, cnt);
- data[ei++] = FIELD_GET(MT_ETBF_TX_EBF_CNT, cnt);
+ data[ei++] = mib->tx_bf_ibf_ppdu_cnt;
+ data[ei++] = mib->tx_bf_ebf_ppdu_cnt;

/* Tx Beamformer Rx feedback monitor */
- cnt = mt76_rr(dev, MT_ETBF_RX_FB_CNT(ext_phy));
- data[ei++] = FIELD_GET(MT_ETBF_RX_FB_ALL, cnt);
- data[ei++] = FIELD_GET(MT_ETBF_RX_FB_HE, cnt);
- data[ei++] = FIELD_GET(MT_ETBF_RX_FB_VHT, cnt);
- data[ei++] = FIELD_GET(MT_ETBF_RX_FB_HT, cnt);
+ data[ei++] = mib->tx_bf_rx_fb_all_cnt;
+ data[ei++] = mib->tx_bf_rx_fb_he_cnt;
+ data[ei++] = mib->tx_bf_rx_fb_vht_cnt;
+ data[ei++] = mib->tx_bf_rx_fb_ht_cnt;

- cnt = mt76_rr(dev, MT_ETBF_RX_FB_CONT(ext_phy));
- data[ei++] = FIELD_GET(MT_ETBF_RX_FB_BW, cnt);
- data[ei++] = FIELD_GET(MT_ETBF_RX_FB_NC, cnt);
- data[ei++] = FIELD_GET(MT_ETBF_RX_FB_NR, cnt);
+ data[ei++] = mib->tx_bf_rx_fb_bw;
+ data[ei++] = mib->tx_bf_rx_fb_nc_cnt;
+ data[ei++] = mib->tx_bf_rx_fb_nr_cnt;

/* Tx Beamformee Rx NDPA & Tx feedback report */
- cnt = mt76_rr(dev, MT_ETBF_TX_NDP_BFRP(ext_phy));
- data[ei++] = FIELD_GET(MT_ETBF_TX_FB_CPL, cnt);
- data[ei++] = FIELD_GET(MT_ETBF_TX_FB_TRI, cnt);
+ data[ei++] = mib->tx_bf_fb_cpl_cnt;
+ data[ei++] = mib->tx_bf_fb_trig_cnt;

/* Tx SU & MU counters */
data[ei++] = mib->tx_bf_cnt;
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
index 26f2befc46dd..565766debb5e 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
@@ -110,6 +110,7 @@ struct mt7915_vif {
struct cfg80211_bitrate_mask bitrate_mask;
};

+/* per-phy stats. */
struct mib_stats {
u32 ack_fail_cnt;
u32 fcs_err_cnt;
@@ -120,6 +121,20 @@ struct mib_stats {
u32 tx_mu_mpdu_cnt;
u32 tx_mu_acked_mpdu_cnt;
u32 tx_su_acked_mpdu_cnt;
+ u32 tx_bf_ibf_ppdu_cnt;
+ u32 tx_bf_ebf_ppdu_cnt;
+
+ u32 tx_bf_rx_fb_all_cnt;
+ u32 tx_bf_rx_fb_he_cnt;
+ u32 tx_bf_rx_fb_vht_cnt;
+ u32 tx_bf_rx_fb_ht_cnt;
+
+ u32 tx_bf_rx_fb_bw; /* value of last sample, not cumulative */
+ u32 tx_bf_rx_fb_nc_cnt;
+ u32 tx_bf_rx_fb_nr_cnt;
+ u32 tx_bf_fb_cpl_cnt;
+ u32 tx_bf_fb_trig_cnt;
+
/* Add more stats here, updated from mac_update_stats */
};

--
2.20.1

2021-07-23 15:49:53

by Ben Greear

[permalink] [raw]
Subject: [PATCH v4 6/8] mt76 - mt7915: Fix he_mcs capabilities for 160mhz.

From: Ben Greear <[email protected]>

At 160, this chip can only do 2x2 NSS. Fix the features
accordingly, verified it shows up properly in iw phy foo info
now.

Signed-off-by: Ben Greear <[email protected]>
---
drivers/net/wireless/mediatek/mt76/mt7915/init.c | 15 +++++++++++----
1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/init.c b/drivers/net/wireless/mediatek/mt76/mt7915/init.c
index 08fa918c310b..f174cf219724 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/init.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/init.c
@@ -614,12 +614,19 @@ mt7915_init_he_caps(struct mt7915_phy *phy, enum nl80211_band band,
{
int i, idx = 0, nss = hweight8(phy->mt76->chainmask);
u16 mcs_map = 0;
+ u16 mcs_map_160 = 0;

for (i = 0; i < 8; i++) {
if (i < nss)
mcs_map |= (IEEE80211_HE_MCS_SUPPORT_0_11 << (i * 2));
else
mcs_map |= (IEEE80211_HE_MCS_NOT_SUPPORTED << (i * 2));
+
+ /* Can do 1/2 of NSS streams in 160Mhz mode. */
+ if (i < nss / 2)
+ mcs_map_160 |= (IEEE80211_HE_MCS_SUPPORT_0_11 << (i * 2));
+ else
+ mcs_map_160 |= (IEEE80211_HE_MCS_NOT_SUPPORTED << (i * 2));
}

for (i = 0; i < NUM_NL80211_IFTYPES; i++) {
@@ -721,10 +728,10 @@ mt7915_init_he_caps(struct mt7915_phy *phy, enum nl80211_band band,

he_mcs->rx_mcs_80 = cpu_to_le16(mcs_map);
he_mcs->tx_mcs_80 = cpu_to_le16(mcs_map);
- he_mcs->rx_mcs_160 = cpu_to_le16(mcs_map);
- he_mcs->tx_mcs_160 = cpu_to_le16(mcs_map);
- he_mcs->rx_mcs_80p80 = cpu_to_le16(mcs_map);
- he_mcs->tx_mcs_80p80 = cpu_to_le16(mcs_map);
+ he_mcs->rx_mcs_160 = cpu_to_le16(mcs_map_160);
+ he_mcs->tx_mcs_160 = cpu_to_le16(mcs_map_160);
+ he_mcs->rx_mcs_80p80 = cpu_to_le16(mcs_map_160);
+ he_mcs->tx_mcs_80p80 = cpu_to_le16(mcs_map_160);

mt7915_set_stream_he_txbf_caps(he_cap, i, nss);

--
2.20.1

2021-07-23 15:49:53

by Ben Greear

[permalink] [raw]
Subject: [PATCH v4 7/8] mt76 - mt7915: Add more MIB registers.

From: Ben Greear <[email protected]>

Add register definitions and read & accumulate them in
the mib polling logic. Note that some registers should not
be read since firmware is already reading them. If driver
reads those, they will be cleared-on-read, and so the firmware
stats will be incorrect.

For these 'do-not-read' stats, add them to the registers definition
so that other developers can be aware of these constraints, but do
not actually read them in the driver.

Signed-off-by: Ben Greear <[email protected]>
---
.../net/wireless/mediatek/mt76/mt7915/mac.c | 65 +++++++++++
.../wireless/mediatek/mt76/mt7915/mt7915.h | 25 ++++-
.../net/wireless/mediatek/mt76/mt7915/regs.h | 105 ++++++++++++++++++
3 files changed, 194 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
index c395600b378a..1b0a44884569 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
@@ -1894,6 +1894,71 @@ mt7915_mac_update_stats(struct mt7915_phy *phy)

mib->fcs_err_cnt += mt76_get_field(dev, MT_MIB_SDR3(ext_phy),
MT_MIB_SDR3_FCS_ERR_MASK);
+
+ cnt = mt76_rr(dev, MT_MIB_SDR4(ext_phy));
+ mib->rx_fifo_full_cnt += FIELD_GET(MT_MIB_SDR4_RX_FIFO_FULL_MASK, cnt);
+
+ cnt = mt76_rr(dev, MT_MIB_SDR5(ext_phy));
+ mib->rx_mpdu_cnt += cnt;
+
+ cnt = mt76_rr(dev, MT_MIB_SDR6(ext_phy));
+ mib->channel_idle_cnt += FIELD_GET(MT_MIB_SDR6_CHANNEL_IDL_CNT_MASK, cnt);
+
+ cnt = mt76_rr(dev, MT_MIB_SDR7(ext_phy));
+ mib->rx_vector_mismatch_cnt += FIELD_GET(MT_MIB_SDR7_RX_VECTOR_MISMATCH_CNT_MASK, cnt);
+
+ cnt = mt76_rr(dev, MT_MIB_SDR8(ext_phy));
+ mib->rx_delimiter_fail_cnt += FIELD_GET(MT_MIB_SDR8_RX_DELIMITER_FAIL_CNT_MASK, cnt);
+
+ cnt = mt76_rr(dev, MT_MIB_SDR11(ext_phy));
+ mib->rx_len_mismatch_cnt += FIELD_GET(MT_MIB_SDR11_RX_LEN_MISMATCH_CNT_MASK, cnt);
+
+ cnt = mt76_rr(dev, MT_MIB_SDR12(ext_phy));
+ mib->tx_ampdu_cnt += cnt;
+
+ cnt = mt76_rr(dev, MT_MIB_SDR13(ext_phy));
+ mib->tx_stop_q_empty_cnt += FIELD_GET(MT_MIB_SDR13_TX_STOP_Q_EMPTY_CNT_MASK, cnt);
+
+ cnt = mt76_rr(dev, MT_MIB_SDR14(ext_phy));
+ mib->tx_mpdu_attempts_cnt += FIELD_GET(MT_MIB_SDR14_TX_MPDU_ATTEMPTS_CNT_MASK, cnt);
+
+ cnt = mt76_rr(dev, MT_MIB_SDR15(ext_phy));
+ mib->tx_mpdu_success_cnt += FIELD_GET(MT_MIB_SDR15_TX_MPDU_SUCCESS_CNT_MASK, cnt);
+
+ cnt = mt76_rr(dev, MT_MIB_SDR22(ext_phy));
+ mib->rx_ampdu_cnt += cnt;
+
+ cnt = mt76_rr(dev, MT_MIB_SDR23(ext_phy));
+ mib->rx_ampdu_bytes_cnt += cnt;
+
+ cnt = mt76_rr(dev, MT_MIB_SDR24(ext_phy));
+ mib->rx_ampdu_valid_subframe_cnt += FIELD_GET(MT_MIB_SDR24_RX_AMPDU_SF_CNT_MASK, cnt);
+
+ cnt = mt76_rr(dev, MT_MIB_SDR25(ext_phy));
+ mib->rx_ampdu_valid_subframe_bytes_cnt += cnt;
+
+ cnt = mt76_rr(dev, MT_MIB_SDR27(ext_phy));
+ mib->tx_rwp_fail_cnt += FIELD_GET(MT_MIB_SDR27_TX_RWP_FAIL_CNT_MASK, cnt);
+
+ cnt = mt76_rr(dev, MT_MIB_SDR28(ext_phy));
+ mib->tx_rwp_need_cnt += FIELD_GET(MT_MIB_SDR28_TX_RWP_NEED_CNT_MASK, cnt);
+
+ cnt = mt76_rr(dev, MT_MIB_SDR29(ext_phy));
+ mib->rx_pfdrop_cnt += FIELD_GET(MT_MIB_SDR29_RX_PFDROP_CNT_MASK, cnt);
+
+ cnt = mt76_rr(dev, MT_MIB_SDR30(ext_phy));
+ mib->rx_vec_queue_overflow_drop_cnt +=
+ FIELD_GET(MT_MIB_SDR30_RX_VEC_QUEUE_OVERFLOW_DROP_CNT_MASK, cnt);
+
+ cnt = mt76_rr(dev, MT_MIB_SDR31(ext_phy));
+ mib->rx_ba_cnt += cnt;
+
+ cnt = mt76_rr(dev, MT_MIB_SDR32(ext_phy));
+ mib->tx_pkt_ebf_cnt += FIELD_GET(MT_MIB_SDR32_TX_PKT_EBF_CNT_MASK, cnt);
+
+ cnt = mt76_rr(dev, MT_MIB_SDR33(ext_phy));
+ mib->tx_pkt_ibf_cnt += FIELD_GET(MT_MIB_SDR33_TX_PKT_IBF_CNT_MASK, cnt);
+
cnt = mt76_rr(dev, MT_MIB_SDR34(ext_phy));
mib->tx_bf_cnt += FIELD_GET(MT_MIB_MU_BF_TX_CNT, cnt);

diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
index 565766debb5e..8c494be272c5 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
@@ -135,7 +135,30 @@ struct mib_stats {
u32 tx_bf_fb_cpl_cnt;
u32 tx_bf_fb_trig_cnt;

- /* Add more stats here, updated from mac_update_stats */
+ u32 tx_ampdu_cnt;
+ u32 tx_stop_q_empty_cnt;
+ u32 tx_mpdu_attempts_cnt;
+ u32 tx_mpdu_success_cnt;
+ u32 tx_pkt_ebf_cnt;
+ u32 tx_pkt_ibf_cnt;
+
+ u32 tx_rwp_fail_cnt;
+ u32 tx_rwp_need_cnt;
+
+ /* rx stats */
+ u32 rx_fifo_full_cnt;
+ u32 channel_idle_cnt;
+ u32 rx_vector_mismatch_cnt;
+ u32 rx_delimiter_fail_cnt;
+ u32 rx_len_mismatch_cnt;
+ u32 rx_mpdu_cnt;
+ u32 rx_ampdu_cnt;
+ u32 rx_ampdu_bytes_cnt;
+ u32 rx_ampdu_valid_subframe_cnt;
+ u32 rx_ampdu_valid_subframe_bytes_cnt;
+ u32 rx_pfdrop_cnt;
+ u32 rx_vec_queue_overflow_drop_cnt;
+ u32 rx_ba_cnt;
};

struct mt7915_hif {
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/regs.h b/drivers/net/wireless/mediatek/mt76/mt7915/regs.h
index a213b5cb82f8..62cc32a098fc 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/regs.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/regs.h
@@ -128,15 +128,120 @@
#define MT_LPON_TCR_SW_READ GENMASK(1, 0)

/* MIB: band 0(0x24800), band 1(0xa4800) */
+/* These counters are (mostly?) clear-on-read. So, some should not
+ * be read at all in case firmware is already reading them. These
+ * are commented with 'DNR' below. The DNR stats will be read by querying
+ * the firmware API for the appropriate message. For counters the driver
+ * does read, the driver should accumulate the counters.
+ */
#define MT_WF_MIB_BASE(_band) ((_band) ? 0xa4800 : 0x24800)
#define MT_WF_MIB(_band, ofs) (MT_WF_MIB_BASE(_band) + (ofs))

+#define MT_MIB_SDR0(_band) MT_WF_MIB(_band, 0x010)
+#define MT_MIB_SDR0_BERACON_TX_CNT_MASK GENMASK(15, 0)
+
#define MT_MIB_SDR3(_band) MT_WF_MIB(_band, 0x014)
#define MT_MIB_SDR3_FCS_ERR_MASK GENMASK(15, 0)

+#define MT_MIB_SDR4(_band) MT_WF_MIB(_band, 0x018)
+#define MT_MIB_SDR4_RX_FIFO_FULL_MASK GENMASK(15, 0)
+
+/* rx mpdu counter, full 32 bits */
+#define MT_MIB_SDR5(_band) MT_WF_MIB(_band, 0x01c)
+
+#define MT_MIB_SDR6(_band) MT_WF_MIB(_band, 0x020)
+#define MT_MIB_SDR6_CHANNEL_IDL_CNT_MASK GENMASK(15, 0)
+
+#define MT_MIB_SDR7(_band) MT_WF_MIB(_band, 0x024)
+#define MT_MIB_SDR7_RX_VECTOR_MISMATCH_CNT_MASK GENMASK(15, 0)
+
+#define MT_MIB_SDR8(_band) MT_WF_MIB(_band, 0x028)
+#define MT_MIB_SDR8_RX_DELIMITER_FAIL_CNT_MASK GENMASK(15, 0)
+
+/* aka CCA_NAV_TX_TIME */
+#define MT_MIB_SDR9_DNR(_band) MT_WF_MIB(_band, 0x02c)
+#define MT_MIB_SDR9_CCA_BUSY_TIME_MASK GENMASK(23, 0)
+
+#define MT_MIB_SDR10_DNR(_band) MT_WF_MIB(_band, 0x030)
+#define MT_MIB_SDR10_MRDY_COUNT_MASK GENMASK(25, 0)
+
+#define MT_MIB_SDR11(_band) MT_WF_MIB(_band, 0x034)
+#define MT_MIB_SDR11_RX_LEN_MISMATCH_CNT_MASK GENMASK(15, 0)
+
+/* tx ampdu cnt, full 32 bits */
+#define MT_MIB_SDR12(_band) MT_WF_MIB(_band, 0x038)
+
+#define MT_MIB_SDR13(_band) MT_WF_MIB(_band, 0x03c)
+#define MT_MIB_SDR13_TX_STOP_Q_EMPTY_CNT_MASK GENMASK(15, 0)
+
+/* counts all mpdus in ampdu, regardless of success */
+#define MT_MIB_SDR14(_band) MT_WF_MIB(_band, 0x040)
+#define MT_MIB_SDR14_TX_MPDU_ATTEMPTS_CNT_MASK GENMASK(23, 0)
+
+/* counts all successfully tx'd mpdus in ampdu */
+#define MT_MIB_SDR15(_band) MT_WF_MIB(_band, 0x044)
+#define MT_MIB_SDR15_TX_MPDU_SUCCESS_CNT_MASK GENMASK(23, 0)
+
+/* in units of 'us' */
+#define MT_MIB_SDR16_DNR(_band) MT_WF_MIB(_band, 0x048)
+#define MT_MIB_SDR16_PRIMARY_CCA_BUSY_TIME_MASK GENMASK(23, 0)
+
+#define MT_MIB_SDR17_DNR(_band) MT_WF_MIB(_band, 0x04c)
+#define MT_MIB_SDR17_SECONDARY_CCA_BUSY_TIME_MASK GENMASK(23, 0)
+
+#define MT_MIB_SDR18(_band) MT_WF_MIB(_band, 0x050)
+#define MT_MIB_SDR18_PRIMARY_ENERGY_DETECT_TIME_MASK GENMASK(23, 0)
+
+/* units are us */
+#define MT_MIB_SDR19_DNR(_band) MT_WF_MIB(_band, 0x054)
+#define MT_MIB_SDR19_CCK_MDRDY_TIME_MASK GENMASK(23, 0)
+
+#define MT_MIB_SDR20_DNR(_band) MT_WF_MIB(_band, 0x058)
+#define MT_MIB_SDR20_OFDM_VHT_MDRDY_TIME_MASK GENMASK(23, 0)
+
+#define MT_MIB_SDR21_DNR(_band) MT_WF_MIB(_band, 0x05c)
+#define MT_MIB_SDR20_GREEN_MDRDY_TIME_MASK GENMASK(23, 0)
+
+/* rx ampdu count, 32-bit */
+#define MT_MIB_SDR22(_band) MT_WF_MIB(_band, 0x060)
+
+/* rx ampdu bytes count, 32-bit */
+#define MT_MIB_SDR23(_band) MT_WF_MIB(_band, 0x064)
+
+/* rx ampdu valid subframe count */
+#define MT_MIB_SDR24(_band) MT_WF_MIB(_band, 0x068)
+#define MT_MIB_SDR24_RX_AMPDU_SF_CNT_MASK GENMASK(23, 0)
+
+/* rx ampdu valid subframe bytes count, 32bits */
+#define MT_MIB_SDR25(_band) MT_WF_MIB(_band, 0x06c)
+
+/* remaining windows protected stats */
+#define MT_MIB_SDR27(_band) MT_WF_MIB(_band, 0x074)
+#define MT_MIB_SDR27_TX_RWP_FAIL_CNT_MASK GENMASK(15, 0)
+
+#define MT_MIB_SDR28(_band) MT_WF_MIB(_band, 0x078)
+#define MT_MIB_SDR28_TX_RWP_NEED_CNT_MASK GENMASK(15, 0)
+
+#define MT_MIB_SDR29(_band) MT_WF_MIB(_band, 0x07c)
+#define MT_MIB_SDR29_RX_PFDROP_CNT_MASK GENMASK(7, 0)
+
+#define MT_MIB_SDR30(_band) MT_WF_MIB(_band, 0x080)
+#define MT_MIB_SDR30_RX_VEC_QUEUE_OVERFLOW_DROP_CNT_MASK GENMASK(15, 0)
+
+/* rx blockack count, 32 bits */
+#define MT_MIB_SDR31(_band) MT_WF_MIB(_band, 0x084)
+
+#define MT_MIB_SDR32(_band) MT_WF_MIB(_band, 0x088)
+#define MT_MIB_SDR32_TX_PKT_EBF_CNT_MASK GENMASK(15, 0)
+
+#define MT_MIB_SDR33(_band) MT_WF_MIB(_band, 0x08c)
+#define MT_MIB_SDR33_TX_PKT_IBF_CNT_MASK GENMASK(15, 0)
+
#define MT_MIB_SDR34(_band) MT_WF_MIB(_band, 0x090)
#define MT_MIB_MU_BF_TX_CNT GENMASK(15, 0)

+/* 36, 37 both DNR */
+
#define MT_MIB_DR8(_band) MT_WF_MIB(_band, 0x0c0)
#define MT_MIB_DR9(_band) MT_WF_MIB(_band, 0x0c4)
#define MT_MIB_DR11(_band) MT_WF_MIB(_band, 0x0cc)
--
2.20.1

2021-07-23 15:50:04

by Ben Greear

[permalink] [raw]
Subject: [PATCH v4 8/8] mt76 - mt7915: Add mib counters to ethtool stats.

From: Ben Greear <[email protected]>

This adds the new mib counters from last patch into ethtool
stats.

Signed-off-by: Ben Greear <[email protected]>
---
.../net/wireless/mediatek/mt76/mt7915/main.c | 49 ++++++++++++++++++-
1 file changed, 48 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/main.c b/drivers/net/wireless/mediatek/mt76/mt7915/main.c
index 885e35bf0fe8..49af7f4d56ba 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/main.c
@@ -1029,6 +1029,14 @@ static void mt7915_sta_set_decap_offload(struct ieee80211_hw *hw,
}

static const char mt7915_gstrings_stats[][ETH_GSTRING_LEN] = {
+ "tx_ampdu_cnt",
+ "tx_stop_q_empty_cnt",
+ "tx_mpdu_attempts",
+ "tx_mpdu_success",
+ "tx_rwp_fail_cnt",
+ "tx_rwp_need_cnt",
+ "tx_pkt_ebf_cnt",
+ "tx_pkt_ibf_cnt",
"tx_ampdu_len:0-1",
"tx_ampdu_len:2-10",
"tx_ampdu_len:11-19",
@@ -1068,6 +1076,22 @@ static const char mt7915_gstrings_stats[][ETH_GSTRING_LEN] = {
"tx_msdu_pack_6",
"tx_msdu_pack_7",
"tx_msdu_pack_8",
+
+ /* rx counters */
+ "rx_fifo_full_cnt",
+ "rx_mpdu_cnt",
+ "channel_idle_cnt",
+ "rx_vector_mismatch_cnt",
+ "rx_delimiter_fail_cnt",
+ "rx_len_mismatch_cnt",
+ "rx_ampdu_cnt",
+ "rx_ampdu_bytes_cnt",
+ "rx_ampdu_valid_subframe_cnt",
+ "rx_ampdu_valid_subframe_b_cnt",
+ "rx_pfdrop_cnt",
+ "rx_vec_queue_overflow_drop_cnt",
+ "rx_ba_cnt",
+
/* per vif counters */
"v_tx_mpdu_attempts",
"v_tx_mpdu_fail",
@@ -1141,6 +1165,15 @@ void mt7915_get_et_stats(struct ieee80211_hw *hw,
if (!phy)
return;

+ data[ei++] = mib->tx_ampdu_cnt;
+ data[ei++] = mib->tx_stop_q_empty_cnt;
+ data[ei++] = mib->tx_mpdu_attempts_cnt;
+ data[ei++] = mib->tx_mpdu_success_cnt;
+ data[ei++] = mib->tx_rwp_fail_cnt;
+ data[ei++] = mib->tx_rwp_need_cnt;
+ data[ei++] = mib->tx_pkt_ebf_cnt;
+ data[ei++] = mib->tx_pkt_ibf_cnt;
+
/* Tx ampdu stat */
n = ext_phy ? ARRAY_SIZE(dev->mt76.aggr_stats) / 2 : 0;
for (i = 0; i < 15 /*ARRAY_SIZE(bound)*/; i++)
@@ -1172,12 +1205,26 @@ void mt7915_get_et_stats(struct ieee80211_hw *hw,
data[ei++] = mib->tx_mu_acked_mpdu_cnt;
data[ei++] = mib->tx_su_acked_mpdu_cnt;

- /* TODO: External phy too?? */

/* Tx amsdu info (pack-count histogram) */
for (i = 0; i < 8; i++)
data[ei++] = mt76_rr(dev, MT_PLE_AMSDU_PACK_MSDU_CNT(i));

+ /* rx counters */
+ data[ei++] = mib->rx_fifo_full_cnt;
+ data[ei++] = mib->rx_mpdu_cnt;
+ data[ei++] = mib->channel_idle_cnt;
+ data[ei++] = mib->rx_vector_mismatch_cnt;
+ data[ei++] = mib->rx_delimiter_fail_cnt;
+ data[ei++] = mib->rx_len_mismatch_cnt;
+ data[ei++] = mib->rx_ampdu_cnt;
+ data[ei++] = mib->rx_ampdu_bytes_cnt;
+ data[ei++] = mib->rx_ampdu_valid_subframe_cnt;
+ data[ei++] = mib->rx_ampdu_valid_subframe_bytes_cnt;
+ data[ei++] = mib->rx_pfdrop_cnt;
+ data[ei++] = mib->rx_vec_queue_overflow_drop_cnt;
+ data[ei++] = mib->rx_ba_cnt;
+
/* Add values for all stations owned by this vif */

/* See mt76_get_min_avr_rssi for example of how to find all sta
--
2.20.1

2021-07-24 12:39:46

by Lorenzo Bianconi

[permalink] [raw]
Subject: Re: [PATCH v4 1/8] mt76 - mt7915: Add ethtool stats support.

> From: Ben Greear <[email protected]>
>
> This exposes some tx-path stats to the ethtool API, so that
> ethtool -S wlanX provides some more useful info.
>
> Signed-off-by: Ben Greear <[email protected]>
> ---
>
> v4: move ethtool code to main.c
> Re-work the 2/8 patch per review.
> Did not try to refactor the station walk per comments on 3/8, I saw
> no clean way to do that.
>
> .../net/wireless/mediatek/mt76/mt7915/main.c | 136 ++++++++++++++++++
> 1 file changed, 136 insertions(+)
>
> diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/main.c b/drivers/net/wireless/mediatek/mt76/mt7915/main.c
> index 48b5e2051bad..d0288fe2abdf 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt7915/main.c
> +++ b/drivers/net/wireless/mediatek/mt76/mt7915/main.c
> @@ -1028,6 +1028,139 @@ static void mt7915_sta_set_decap_offload(struct ieee80211_hw *hw,
> mt7915_mcu_sta_update_hdr_trans(dev, vif, sta);
> }
>
> +static const char mt7915_gstrings_stats[][ETH_GSTRING_LEN] = {
> + "tx_ampdu_len:0-1",
> + "tx_ampdu_len:2-10",
> + "tx_ampdu_len:11-19",
> + "tx_ampdu_len:20-28",
> + "tx_ampdu_len:29-37",
> + "tx_ampdu_len:38-46",
> + "tx_ampdu_len:47-55",
> + "tx_ampdu_len:56-79",
> + "tx_ampdu_len:80-103",
> + "tx_ampdu_len:104-127",
> + "tx_ampdu_len:128-151",
> + "tx_ampdu_len:152-175",
> + "tx_ampdu_len:176-199",
> + "tx_ampdu_len:200-223",
> + "tx_ampdu_len:224-247",
> + "ba_miss_count",
> + "tx_beamformer_ppdu_iBF",
> + "tx_beamformer_ppdu_eBF",
> + "tx_beamformer_rx_feedback_all",
> + "tx_beamformer_rx_feedback_he",
> + "tx_beamformer_rx_feedback_vht",
> + "tx_beamformer_rx_feedback_ht",
> + "tx_beamformer_rx_feedback_bw", /* zero based idx: 20, 40, 80, 160 */
> + "tx_beamformer_rx_feedback_nc",
> + "tx_beamformer_rx_feedback_nr",
> + "tx_beamformee_ok_feedback_pkts",
> + "tx_beamformee_feedback_trig",
> + "tx_mu_beamforming",
> + "tx_mu_mpdu",
> + "tx_mu_successful_mpdu",
> + "tx_su_successful_mpdu",
> + "tx_msdu_pack_1",
> + "tx_msdu_pack_2",
> + "tx_msdu_pack_3",
> + "tx_msdu_pack_4",
> + "tx_msdu_pack_5",
> + "tx_msdu_pack_6",
> + "tx_msdu_pack_7",
> + "tx_msdu_pack_8",
> +};
> +
> +#define MT7915_SSTATS_LEN ARRAY_SIZE(mt7915_gstrings_stats)
> +
> +/* Ethtool related API */
> +void mt7915_get_et_strings(struct ieee80211_hw *hw,
> + struct ieee80211_vif *vif,
> + u32 sset, u8 *data)

please make them static

Regards,
Lorenzo

> +{
> + if (sset == ETH_SS_STATS)
> + memcpy(data, *mt7915_gstrings_stats,
> + sizeof(mt7915_gstrings_stats));
> +}
> +
> +int mt7915_get_et_sset_count(struct ieee80211_hw *hw,
> + struct ieee80211_vif *vif, int sset)
> +{
> + if (sset == ETH_SS_STATS)
> + return MT7915_SSTATS_LEN;
> +
> + return 0;
> +}
> +
> +void mt7915_get_et_stats(struct ieee80211_hw *hw,
> + struct ieee80211_vif *vif,
> + struct ethtool_stats *stats, u64 *data)
> +{
> + struct mt7915_dev *dev = mt7915_hw_dev(hw);
> + struct mt7915_phy *phy = mt7915_hw_phy(hw);
> +
> + /* TODO: These are mostly dev-wide stats at this point.
> + * Get some per-vif stats?
> + */
> +
> + /* See mt7915_ampdu_stat_read_phy, etc */
> + bool ext_phy = phy != &dev->phy;
> + int i, n, cnt;
> + int ei = 0;
> +
> + if (!phy)
> + return;
> +
> + /* Tx ampdu stat */
> + n = ext_phy ? ARRAY_SIZE(dev->mt76.aggr_stats) / 2 : 0;
> + for (i = 0; i < 15 /*ARRAY_SIZE(bound)*/; i++)
> + data[ei++] = dev->mt76.aggr_stats[i + n];
> +
> + data[ei++] = phy->mib.ba_miss_cnt;
> +
> + /* Tx Beamformer monitor */
> + cnt = mt76_rr(dev, MT_ETBF_TX_APP_CNT(ext_phy));
> + data[ei++] = FIELD_GET(MT_ETBF_TX_IBF_CNT, cnt);
> + data[ei++] = FIELD_GET(MT_ETBF_TX_EBF_CNT, cnt);
> +
> + /* Tx Beamformer Rx feedback monitor */
> + cnt = mt76_rr(dev, MT_ETBF_RX_FB_CNT(ext_phy));
> + data[ei++] = FIELD_GET(MT_ETBF_RX_FB_ALL, cnt);
> + data[ei++] = FIELD_GET(MT_ETBF_RX_FB_HE, cnt);
> + data[ei++] = FIELD_GET(MT_ETBF_RX_FB_VHT, cnt);
> + data[ei++] = FIELD_GET(MT_ETBF_RX_FB_HT, cnt);
> +
> + cnt = mt76_rr(dev, MT_ETBF_RX_FB_CONT(ext_phy));
> + data[ei++] = FIELD_GET(MT_ETBF_RX_FB_BW, cnt);
> + data[ei++] = FIELD_GET(MT_ETBF_RX_FB_NC, cnt);
> + data[ei++] = FIELD_GET(MT_ETBF_RX_FB_NR, cnt);
> +
> + /* Tx Beamformee Rx NDPA & Tx feedback report */
> + cnt = mt76_rr(dev, MT_ETBF_TX_NDP_BFRP(ext_phy));
> + data[ei++] = FIELD_GET(MT_ETBF_TX_FB_CPL, cnt);
> + data[ei++] = FIELD_GET(MT_ETBF_TX_FB_TRI, cnt);
> +
> + /* Tx SU & MU counters */
> + cnt = mt76_rr(dev, MT_MIB_SDR34(ext_phy));
> + data[ei++] = FIELD_GET(MT_MIB_MU_BF_TX_CNT, cnt);
> +
> + cnt = mt76_rr(dev, MT_MIB_DR8(ext_phy));
> + data[ei++] = cnt;
> +
> + cnt = mt76_rr(dev, MT_MIB_DR9(ext_phy));
> + data[ei++] = cnt; /* MU MPDU SUccessful */
> +
> + cnt = mt76_rr(dev, MT_MIB_DR11(ext_phy));
> + data[ei++] = cnt; /* SU MPDU successful */
> +
> + /* TODO: External phy too?? */
> +
> + /* Tx amsdu info (pack-count histogram) */
> + for (i = 0; i < 8; i++)
> + data[ei++] = mt76_rr(dev, MT_PLE_AMSDU_PACK_MSDU_CNT(i));
> +
> + WARN_ON(ei != MT7915_SSTATS_LEN);
> +}
> +
> const struct ieee80211_ops mt7915_ops = {
> .tx = mt7915_tx,
> .start = mt7915_start,
> @@ -1052,6 +1185,9 @@ const struct ieee80211_ops mt7915_ops = {
> .get_txpower = mt76_get_txpower,
> .channel_switch_beacon = mt7915_channel_switch_beacon,
> .get_stats = mt7915_get_stats,
> + .get_et_sset_count = mt7915_get_et_sset_count,
> + .get_et_stats = mt7915_get_et_stats,
> + .get_et_strings = mt7915_get_et_strings,
> .get_tsf = mt7915_get_tsf,
> .set_tsf = mt7915_set_tsf,
> .offset_tsf = mt7915_offset_tsf,
> --
> 2.20.1
>


Attachments:
(No filename) (5.60 kB)
signature.asc (235.00 B)
Download all attachments

2021-07-24 12:40:08

by Lorenzo Bianconi

[permalink] [raw]
Subject: Re: [PATCH v4 4/8] mt76 - mt7915: Add tx mu/su counters to mib

> From: Ben Greear <[email protected]>
>
> These counters are clear-on-read, so we need to accumulate
> them in the update_stats poll logic, and read the accumulated
> values instead of directly doing register reads when reporting
> to debugfs and ethtool stats.
>
> Signed-off-by: Ben Greear <[email protected]>
> ---
> .../net/wireless/mediatek/mt76/mt7915/debugfs.c | 17 ++++++++---------
> drivers/net/wireless/mediatek/mt76/mt7915/mac.c | 13 ++++++++++++-
> .../net/wireless/mediatek/mt76/mt7915/main.c | 16 +++++-----------
> .../net/wireless/mediatek/mt76/mt7915/mt7915.h | 4 ++++
> 4 files changed, 29 insertions(+), 21 deletions(-)
>
> diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c b/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c
> index 1a48b09d0cb7..35248d182728 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c
> +++ b/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c
> @@ -152,6 +152,7 @@ mt7915_txbf_stat_read_phy(struct mt7915_phy *phy, struct seq_file *s)
> "BW20", "BW40", "BW80", "BW160"
> };
> int cnt;
> + struct mib_stats *mib = &phy->mib;

according to the check below this can be a NULL pointer dereference

>
> if (!phy)
> return;
> @@ -187,15 +188,13 @@ mt7915_txbf_stat_read_phy(struct mt7915_phy *phy, struct seq_file *s)
> FIELD_GET(MT_ETBF_TX_FB_TRI, cnt));
>
> /* Tx SU & MU counters */
> - cnt = mt76_rr(dev, MT_MIB_SDR34(ext_phy));
> - seq_printf(s, "Tx multi-user Beamforming counts: %ld\n",
> - FIELD_GET(MT_MIB_MU_BF_TX_CNT, cnt));
> - cnt = mt76_rr(dev, MT_MIB_DR8(ext_phy));
> - seq_printf(s, "Tx multi-user MPDU counts: %d\n", cnt);
> - cnt = mt76_rr(dev, MT_MIB_DR9(ext_phy));
> - seq_printf(s, "Tx multi-user successful MPDU counts: %d\n", cnt);
> - cnt = mt76_rr(dev, MT_MIB_DR11(ext_phy));
> - seq_printf(s, "Tx single-user successful MPDU counts: %d\n", cnt);
> + seq_printf(s, "Tx multi-user Beamforming counts: %d\n",
> + mib->tx_bf_cnt);
> + seq_printf(s, "Tx multi-user MPDU counts: %d\n", mib->tx_mu_mpdu_cnt);
> + seq_printf(s, "Tx multi-user successful MPDU counts: %d\n",
> + mib->tx_mu_acked_mpdu_cnt);
> + seq_printf(s, "Tx single-user successful MPDU counts: %d\n",
> + mib->tx_su_acked_mpdu_cnt);
>
> seq_puts(s, "\n");
> }
> diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
> index 6f445999e516..064d754e0565 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
> +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
> @@ -1890,10 +1890,21 @@ mt7915_mac_update_stats(struct mt7915_phy *phy)
> struct mt7915_dev *dev = phy->dev;
> struct mib_stats *mib = &phy->mib;
> bool ext_phy = phy != &dev->phy;
> - int i, aggr0, aggr1;
> + int i, aggr0, aggr1, cnt;
>
> mib->fcs_err_cnt += mt76_get_field(dev, MT_MIB_SDR3(ext_phy),
> MT_MIB_SDR3_FCS_ERR_MASK);
> + cnt = mt76_rr(dev, MT_MIB_SDR34(ext_phy));
> + mib->tx_bf_cnt += FIELD_GET(MT_MIB_MU_BF_TX_CNT, cnt);
> +
> + cnt = mt76_rr(dev, MT_MIB_DR8(ext_phy));
> + mib->tx_mu_mpdu_cnt += cnt;
> +
> + cnt = mt76_rr(dev, MT_MIB_DR9(ext_phy));
> + mib->tx_mu_acked_mpdu_cnt += cnt;
> +
> + cnt = mt76_rr(dev, MT_MIB_DR11(ext_phy));
> + mib->tx_su_acked_mpdu_cnt += cnt;
>
> aggr0 = ext_phy ? ARRAY_SIZE(dev->mt76.aggr_stats) / 2 : 0;
> for (i = 0, aggr1 = aggr0 + 4; i < 4; i++) {
> diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/main.c b/drivers/net/wireless/mediatek/mt76/mt7915/main.c
> index de083008663e..be6444650afe 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt7915/main.c
> +++ b/drivers/net/wireless/mediatek/mt76/mt7915/main.c
> @@ -1131,6 +1131,7 @@ void mt7915_get_et_stats(struct ieee80211_hw *hw,
> struct mt7915_sta *msta;
> struct mt7915_sta_stats *mstats;
> bool found_sta = false;
> + struct mib_stats *mib = &phy->mib;
>
> /* See mt7915_ampdu_stat_read_phy, etc */
> bool ext_phy = phy != &dev->phy;
> @@ -1170,17 +1171,10 @@ void mt7915_get_et_stats(struct ieee80211_hw *hw,
> data[ei++] = FIELD_GET(MT_ETBF_TX_FB_TRI, cnt);
>
> /* Tx SU & MU counters */
> - cnt = mt76_rr(dev, MT_MIB_SDR34(ext_phy));
> - data[ei++] = FIELD_GET(MT_MIB_MU_BF_TX_CNT, cnt);
> -
> - cnt = mt76_rr(dev, MT_MIB_DR8(ext_phy));
> - data[ei++] = cnt;
> -
> - cnt = mt76_rr(dev, MT_MIB_DR9(ext_phy));
> - data[ei++] = cnt; /* MU MPDU SUccessful */
> -
> - cnt = mt76_rr(dev, MT_MIB_DR11(ext_phy));
> - data[ei++] = cnt; /* SU MPDU successful */
> + data[ei++] = mib->tx_bf_cnt;
> + data[ei++] = mib->tx_mu_mpdu_cnt;
> + data[ei++] = mib->tx_mu_acked_mpdu_cnt;
> + data[ei++] = mib->tx_su_acked_mpdu_cnt;
>
> /* TODO: External phy too?? */
>
> diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
> index a8617ba69a21..26f2befc46dd 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
> +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
> @@ -116,6 +116,10 @@ struct mib_stats {
> u32 rts_cnt;
> u32 rts_retries_cnt;
> u32 ba_miss_cnt;
> + u32 tx_bf_cnt;
> + u32 tx_mu_mpdu_cnt;
> + u32 tx_mu_acked_mpdu_cnt;
> + u32 tx_su_acked_mpdu_cnt;
> /* Add more stats here, updated from mac_update_stats */
> };
>
> --
> 2.20.1
>


Attachments:
(No filename) (5.27 kB)
signature.asc (235.00 B)
Download all attachments

2021-07-24 12:41:05

by Lorenzo Bianconi

[permalink] [raw]
Subject: Re: [PATCH v4 5/8] mt76 - mt7915: Move more tx-bf stats to mib.

On Jul 23, [email protected] wrote:
> From: Ben Greear <[email protected]>
>
> These are clear-on-read, so accumulate them in the update_stats
> polling method, then access them via the mib structure
> when reading them from debugfs/ethtool.
>
> Signed-off-by: Ben Greear <[email protected]>
> ---
> .../wireless/mediatek/mt76/mt7915/debugfs.c | 44 +++++++++----------
> .../net/wireless/mediatek/mt76/mt7915/mac.c | 19 ++++++++
> .../net/wireless/mediatek/mt76/mt7915/main.c | 28 +++++-------
> .../wireless/mediatek/mt76/mt7915/mt7915.h | 15 +++++++
> 4 files changed, 66 insertions(+), 40 deletions(-)
>
> diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c b/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c
> index 35248d182728..91664ac63a8d 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c
> +++ b/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c
> @@ -146,46 +146,42 @@ mt7915_ampdu_stat_read_phy(struct mt7915_phy *phy,
> static void
> mt7915_txbf_stat_read_phy(struct mt7915_phy *phy, struct seq_file *s)
> {
> - struct mt7915_dev *dev = s->private;
> - bool ext_phy = phy != &dev->phy;
> static const char * const bw[] = {
> "BW20", "BW40", "BW80", "BW160"
> };
> - int cnt;
> - struct mib_stats *mib = &phy->mib;
> + struct mib_stats *mib;
>
> if (!phy)
> return;
>
> + mib = &phy->mib;

please merge it in the previous patch

> +
> /* Tx Beamformer monitor */
> seq_puts(s, "\nTx Beamformer applied PPDU counts: ");
>
> - cnt = mt76_rr(dev, MT_ETBF_TX_APP_CNT(ext_phy));
> - seq_printf(s, "iBF: %ld, eBF: %ld\n",
> - FIELD_GET(MT_ETBF_TX_IBF_CNT, cnt),
> - FIELD_GET(MT_ETBF_TX_EBF_CNT, cnt));
> + seq_printf(s, "iBF: %d, eBF: %d\n",
> + mib->tx_bf_ibf_ppdu_cnt,
> + mib->tx_bf_ebf_ppdu_cnt);
>
> /* Tx Beamformer Rx feedback monitor */
> seq_puts(s, "Tx Beamformer Rx feedback statistics: ");
>
> - cnt = mt76_rr(dev, MT_ETBF_RX_FB_CNT(ext_phy));
> - seq_printf(s, "All: %ld, HE: %ld, VHT: %ld, HT: %ld, ",
> - FIELD_GET(MT_ETBF_RX_FB_ALL, cnt),
> - FIELD_GET(MT_ETBF_RX_FB_HE, cnt),
> - FIELD_GET(MT_ETBF_RX_FB_VHT, cnt),
> - FIELD_GET(MT_ETBF_RX_FB_HT, cnt));
> - cnt = mt76_rr(dev, MT_ETBF_RX_FB_CONT(ext_phy));
> - seq_printf(s, "%s, NC: %ld, NR: %ld\n",
> - bw[FIELD_GET(MT_ETBF_RX_FB_BW, cnt)],
> - FIELD_GET(MT_ETBF_RX_FB_NC, cnt),
> - FIELD_GET(MT_ETBF_RX_FB_NR, cnt));
> + seq_printf(s, "All: %d, HE: %d, VHT: %d, HT: %d, ",
> + mib->tx_bf_rx_fb_all_cnt,
> + mib->tx_bf_rx_fb_he_cnt,
> + mib->tx_bf_rx_fb_vht_cnt,
> + mib->tx_bf_rx_fb_ht_cnt);
> +
> + seq_printf(s, "%s, NC: %d, NR: %d\n",
> + bw[mib->tx_bf_rx_fb_bw],
> + mib->tx_bf_rx_fb_nc_cnt,
> + mib->tx_bf_rx_fb_nr_cnt);
>
> /* Tx Beamformee Rx NDPA & Tx feedback report */
> - cnt = mt76_rr(dev, MT_ETBF_TX_NDP_BFRP(ext_phy));
> - seq_printf(s, "Tx Beamformee successful feedback frames: %ld\n",
> - FIELD_GET(MT_ETBF_TX_FB_CPL, cnt));
> - seq_printf(s, "Tx Beamformee feedback triggered counts: %ld\n",
> - FIELD_GET(MT_ETBF_TX_FB_TRI, cnt));
> + seq_printf(s, "Tx Beamformee successful feedback frames: %d\n",
> + mib->tx_bf_fb_cpl_cnt);
> + seq_printf(s, "Tx Beamformee feedback triggered counts: %d\n",
> + mib->tx_bf_fb_trig_cnt);
>
> /* Tx SU & MU counters */
> seq_printf(s, "Tx multi-user Beamforming counts: %d\n",
> diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
> index 064d754e0565..c395600b378a 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
> +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
> @@ -1906,6 +1906,25 @@ mt7915_mac_update_stats(struct mt7915_phy *phy)
> cnt = mt76_rr(dev, MT_MIB_DR11(ext_phy));
> mib->tx_su_acked_mpdu_cnt += cnt;
>
> + cnt = mt76_rr(dev, MT_ETBF_TX_APP_CNT(ext_phy));
> + mib->tx_bf_ibf_ppdu_cnt += FIELD_GET(MT_ETBF_TX_IBF_CNT, cnt);
> + mib->tx_bf_ebf_ppdu_cnt += FIELD_GET(MT_ETBF_TX_EBF_CNT, cnt);
> +
> + cnt = mt76_rr(dev, MT_ETBF_RX_FB_CNT(ext_phy));
> + mib->tx_bf_rx_fb_all_cnt += FIELD_GET(MT_ETBF_RX_FB_ALL, cnt);
> + mib->tx_bf_rx_fb_he_cnt += FIELD_GET(MT_ETBF_RX_FB_HE, cnt);
> + mib->tx_bf_rx_fb_vht_cnt += FIELD_GET(MT_ETBF_RX_FB_VHT, cnt);
> + mib->tx_bf_rx_fb_ht_cnt += FIELD_GET(MT_ETBF_RX_FB_HT, cnt);
> +
> + cnt = mt76_rr(dev, MT_ETBF_RX_FB_CONT(ext_phy));
> + mib->tx_bf_rx_fb_bw = FIELD_GET(MT_ETBF_RX_FB_BW, cnt);
> + mib->tx_bf_rx_fb_nc_cnt += FIELD_GET(MT_ETBF_RX_FB_NC, cnt);
> + mib->tx_bf_rx_fb_nr_cnt += FIELD_GET(MT_ETBF_RX_FB_NR, cnt);
> +
> + cnt = mt76_rr(dev, MT_ETBF_TX_NDP_BFRP(ext_phy));
> + mib->tx_bf_fb_cpl_cnt += FIELD_GET(MT_ETBF_TX_FB_CPL, cnt);
> + mib->tx_bf_fb_trig_cnt += FIELD_GET(MT_ETBF_TX_FB_TRI, cnt);
> +
> aggr0 = ext_phy ? ARRAY_SIZE(dev->mt76.aggr_stats) / 2 : 0;
> for (i = 0, aggr1 = aggr0 + 4; i < 4; i++) {
> u32 val;
> diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/main.c b/drivers/net/wireless/mediatek/mt76/mt7915/main.c
> index be6444650afe..885e35bf0fe8 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt7915/main.c
> +++ b/drivers/net/wireless/mediatek/mt76/mt7915/main.c
> @@ -1135,7 +1135,7 @@ void mt7915_get_et_stats(struct ieee80211_hw *hw,
>
> /* See mt7915_ampdu_stat_read_phy, etc */
> bool ext_phy = phy != &dev->phy;
> - int i, j, n, cnt, next_ei;
> + int i, j, n, next_ei;
> int ei = 0;
>
> if (!phy)
> @@ -1149,26 +1149,22 @@ void mt7915_get_et_stats(struct ieee80211_hw *hw,
> data[ei++] = phy->mib.ba_miss_cnt;
>
> /* Tx Beamformer monitor */
> - cnt = mt76_rr(dev, MT_ETBF_TX_APP_CNT(ext_phy));
> - data[ei++] = FIELD_GET(MT_ETBF_TX_IBF_CNT, cnt);
> - data[ei++] = FIELD_GET(MT_ETBF_TX_EBF_CNT, cnt);
> + data[ei++] = mib->tx_bf_ibf_ppdu_cnt;
> + data[ei++] = mib->tx_bf_ebf_ppdu_cnt;
>
> /* Tx Beamformer Rx feedback monitor */
> - cnt = mt76_rr(dev, MT_ETBF_RX_FB_CNT(ext_phy));
> - data[ei++] = FIELD_GET(MT_ETBF_RX_FB_ALL, cnt);
> - data[ei++] = FIELD_GET(MT_ETBF_RX_FB_HE, cnt);
> - data[ei++] = FIELD_GET(MT_ETBF_RX_FB_VHT, cnt);
> - data[ei++] = FIELD_GET(MT_ETBF_RX_FB_HT, cnt);
> + data[ei++] = mib->tx_bf_rx_fb_all_cnt;
> + data[ei++] = mib->tx_bf_rx_fb_he_cnt;
> + data[ei++] = mib->tx_bf_rx_fb_vht_cnt;
> + data[ei++] = mib->tx_bf_rx_fb_ht_cnt;
>
> - cnt = mt76_rr(dev, MT_ETBF_RX_FB_CONT(ext_phy));
> - data[ei++] = FIELD_GET(MT_ETBF_RX_FB_BW, cnt);
> - data[ei++] = FIELD_GET(MT_ETBF_RX_FB_NC, cnt);
> - data[ei++] = FIELD_GET(MT_ETBF_RX_FB_NR, cnt);
> + data[ei++] = mib->tx_bf_rx_fb_bw;
> + data[ei++] = mib->tx_bf_rx_fb_nc_cnt;
> + data[ei++] = mib->tx_bf_rx_fb_nr_cnt;
>
> /* Tx Beamformee Rx NDPA & Tx feedback report */
> - cnt = mt76_rr(dev, MT_ETBF_TX_NDP_BFRP(ext_phy));
> - data[ei++] = FIELD_GET(MT_ETBF_TX_FB_CPL, cnt);
> - data[ei++] = FIELD_GET(MT_ETBF_TX_FB_TRI, cnt);
> + data[ei++] = mib->tx_bf_fb_cpl_cnt;
> + data[ei++] = mib->tx_bf_fb_trig_cnt;
>
> /* Tx SU & MU counters */
> data[ei++] = mib->tx_bf_cnt;
> diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
> index 26f2befc46dd..565766debb5e 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
> +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
> @@ -110,6 +110,7 @@ struct mt7915_vif {
> struct cfg80211_bitrate_mask bitrate_mask;
> };
>
> +/* per-phy stats. */
> struct mib_stats {
> u32 ack_fail_cnt;
> u32 fcs_err_cnt;
> @@ -120,6 +121,20 @@ struct mib_stats {
> u32 tx_mu_mpdu_cnt;
> u32 tx_mu_acked_mpdu_cnt;
> u32 tx_su_acked_mpdu_cnt;
> + u32 tx_bf_ibf_ppdu_cnt;
> + u32 tx_bf_ebf_ppdu_cnt;
> +
> + u32 tx_bf_rx_fb_all_cnt;
> + u32 tx_bf_rx_fb_he_cnt;
> + u32 tx_bf_rx_fb_vht_cnt;
> + u32 tx_bf_rx_fb_ht_cnt;
> +
> + u32 tx_bf_rx_fb_bw; /* value of last sample, not cumulative */
> + u32 tx_bf_rx_fb_nc_cnt;
> + u32 tx_bf_rx_fb_nr_cnt;
> + u32 tx_bf_fb_cpl_cnt;
> + u32 tx_bf_fb_trig_cnt;
> +
> /* Add more stats here, updated from mac_update_stats */
> };
>
> --
> 2.20.1
>


Attachments:
(No filename) (8.05 kB)
signature.asc (235.00 B)
Download all attachments

2021-07-31 07:50:10

by Kalle Valo

[permalink] [raw]
Subject: Re: [PATCH v4 1/8] mt76 - mt7915: Add ethtool stats support.

[email protected] writes:

> From: Ben Greear <[email protected]>
>
> This exposes some tx-path stats to the ethtool API, so that
> ethtool -S wlanX provides some more useful info.
>
> Signed-off-by: Ben Greear <[email protected]>

The subject style mt76 uses is:

mt76: mt7915: Add ethtool stats support

And no period in the end.

--
https://patchwork.kernel.org/project/linux-wireless/list/

https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches

2021-08-02 14:51:14

by Ben Greear

[permalink] [raw]
Subject: Re: [PATCH v4 1/8] mt76 - mt7915: Add ethtool stats support.

On 7/31/21 12:48 AM, Kalle Valo wrote:
> [email protected] writes:
>
>> From: Ben Greear <[email protected]>
>>
>> This exposes some tx-path stats to the ethtool API, so that
>> ethtool -S wlanX provides some more useful info.
>>
>> Signed-off-by: Ben Greear <[email protected]>
>
> The subject style mt76 uses is:
>
> mt76: mt7915: Add ethtool stats support
>
> And no period in the end.

Don't apply the 1/8 series. I merged two patches based on previous
comment so now it is a x/7 series. I'll go through and make sure
I have punctuation correct and re-submit that x/7 as needed.

Thanks,
Ben

--
Ben Greear <[email protected]>
Candela Technologies Inc http://www.candelatech.com