2021-07-22 20:25:46

by Ben Greear

[permalink] [raw]
Subject: [PATCH v3 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]>
---
v3: Clean up checkpatch warnings.

.../wireless/mediatek/mt76/mt7915/debugfs.c | 135 ++++++++++++++++++
.../net/wireless/mediatek/mt76/mt7915/main.c | 3 +
.../wireless/mediatek/mt76/mt7915/mt7915.h | 12 ++
3 files changed, 150 insertions(+)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c b/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c
index 1a48b09d0cb7..469028d641c7 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c
@@ -382,4 +382,139 @@ void mt7915_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
{
debugfs_create_file("fixed_rate", 0600, dir, sta, &fops_fixed_rate);
}
+
#endif
+
+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_debug_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_debug_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_debug_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);
+}
+
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/main.c b/drivers/net/wireless/mediatek/mt76/mt7915/main.c
index 48b5e2051bad..ed94e3c3c51d 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/main.c
@@ -1052,6 +1052,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_debug_get_et_sset_count,
+ .get_et_stats = mt7915_debug_get_et_stats,
+ .get_et_strings = mt7915_debug_get_et_strings,
.get_tsf = mt7915_get_tsf,
.set_tsf = mt7915_set_tsf,
.offset_tsf = mt7915_offset_tsf,
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
index 33be449309e0..a3c78365db23 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
@@ -419,4 +419,16 @@ void mt7915_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
struct ieee80211_sta *sta, struct dentry *dir);
#endif

+/* Ethtool API, implementation found in debugfs.c */
+void mt7915_debug_get_et_strings(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ u32 sset, u8 *data);
+
+int mt7915_debug_get_et_sset_count(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif, int sset);
+
+void mt7915_debug_get_et_stats(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ethtool_stats *stats, u64 *data);
+
#endif
--
2.20.1


2021-07-22 20:25:46

by Ben Greear

[permalink] [raw]
Subject: [PATCH v3 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 | 32 +++++++++++++------
.../wireless/mediatek/mt76/mt7915/mt7915.h | 14 ++++++++
3 files changed, 37 insertions(+), 10 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..3a10e14fbd50 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,20 @@ 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]++;
+ 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 +1397,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;
@@ -1440,15 +1454,13 @@ static void mt7915_mac_add_txs(struct mt7915_dev *dev, void *data)
rcu_read_lock();

wcid = rcu_dereference(dev->mt76.wcid[wcidx]);
- if (!wcid)
+ if (!wcid || !wcid->sta)
goto out;

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

- if (!wcid->sta)
- goto out;
+ mt7915_mac_add_txs_skb(dev, wcid, pid, txs_data, &msta->stats);

- 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 a3c78365db23..ff944d1cf527 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-22 20:27:22

by Ben Greear

[permalink] [raw]
Subject: [PATCH v3 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]>
---
.../wireless/mediatek/mt76/mt7915/debugfs.c | 50 ++++++++++++++++++-
1 file changed, 48 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c b/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c
index 9299208a73ee..a074ecf8ec38 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c
@@ -381,6 +381,14 @@ void mt7915_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
#endif

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",
@@ -420,6 +428,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",
@@ -493,6 +517,15 @@ void mt7915_debug_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++)
@@ -524,12 +557,25 @@ void mt7915_debug_get_et_stats(struct ieee80211_hw *hw,
data[ei++] = mib->tx_mu_successful_mpdu_cnt;
data[ei++] = mib->tx_su_successful_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-22 20:27:34

by Ben Greear

[permalink] [raw]
Subject: [PATCH v3 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 | 72 +++++++++----------
.../net/wireless/mediatek/mt76/mt7915/mac.c | 19 +++++
.../wireless/mediatek/mt76/mt7915/mt7915.h | 15 ++++
3 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 759899c44583..9299208a73ee 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",
@@ -491,7 +487,7 @@ void mt7915_debug_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)
@@ -505,26 +501,22 @@ void mt7915_debug_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/mac.c b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
index 23540ba5da97..abde1b52ad71 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
@@ -1896,6 +1896,25 @@ mt7915_mac_update_stats(struct mt7915_phy *phy)
cnt = mt76_rr(dev, MT_MIB_DR11(ext_phy));
mib->tx_su_successful_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/mt7915.h b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
index c5d0f2331b6f..29a39c24633a 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_successful_mpdu_cnt;
u32 tx_su_successful_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-22 20:53:26

by Lorenzo Bianconi

[permalink] [raw]
Subject: Re: [PATCH v3 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]>
> ---
> v3: Clean up checkpatch warnings.
>
> .../wireless/mediatek/mt76/mt7915/debugfs.c | 135 ++++++++++++++++++
> .../net/wireless/mediatek/mt76/mt7915/main.c | 3 +
> .../wireless/mediatek/mt76/mt7915/mt7915.h | 12 ++
> 3 files changed, 150 insertions(+)
>
> diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c b/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c
> index 1a48b09d0cb7..469028d641c7 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c
> +++ b/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c
> @@ -382,4 +382,139 @@ void mt7915_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
> {
> debugfs_create_file("fixed_rate", 0600, dir, sta, &fops_fixed_rate);
> }
> +

please remove the new line here

> #endif
> +
> +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_debug_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_debug_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;
> +}

are these routine just used in main.c? if so I guess to move them there and
make them static

> +
> +void mt7915_debug_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);
> +}
> +
> diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/main.c b/drivers/net/wireless/mediatek/mt76/mt7915/main.c
> index 48b5e2051bad..ed94e3c3c51d 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt7915/main.c
> +++ b/drivers/net/wireless/mediatek/mt76/mt7915/main.c
> @@ -1052,6 +1052,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_debug_get_et_sset_count,
> + .get_et_stats = mt7915_debug_get_et_stats,
> + .get_et_strings = mt7915_debug_get_et_strings,
> .get_tsf = mt7915_get_tsf,
> .set_tsf = mt7915_set_tsf,
> .offset_tsf = mt7915_offset_tsf,
> diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
> index 33be449309e0..a3c78365db23 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
> +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
> @@ -419,4 +419,16 @@ void mt7915_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
> struct ieee80211_sta *sta, struct dentry *dir);
> #endif
>
> +/* Ethtool API, implementation found in debugfs.c */
> +void mt7915_debug_get_et_strings(struct ieee80211_hw *hw,
> + struct ieee80211_vif *vif,
> + u32 sset, u8 *data);
> +
> +int mt7915_debug_get_et_sset_count(struct ieee80211_hw *hw,
> + struct ieee80211_vif *vif, int sset);
> +
> +void mt7915_debug_get_et_stats(struct ieee80211_hw *hw,
> + struct ieee80211_vif *vif,
> + struct ethtool_stats *stats, u64 *data);
> +
> #endif
> --
> 2.20.1
>


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

2021-07-22 21:48:31

by Lorenzo Bianconi

[permalink] [raw]
Subject: Re: [PATCH v3 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 | 32 +++++++++++++------
> .../wireless/mediatek/mt76/mt7915/mt7915.h | 14 ++++++++
> 3 files changed, 37 insertions(+), 10 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..3a10e14fbd50 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,20 @@ 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]++;
> + stats->tx_mcs[rate.mcs]++;

here, with the patch below, we can have a oob access in tx_mcs array

https://patchwork.kernel.org/project/linux-wireless/patch/[email protected]/

> +
> + mode = FIELD_GET(MT_TX_RATE_MODE, txrate);
> + switch (mode) {
> case MT_PHY_TYPE_CCK:
> cck = true;
> fallthrough;
> @@ -1389,18 +1397,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;
> @@ -1440,15 +1454,13 @@ static void mt7915_mac_add_txs(struct mt7915_dev *dev, void *data)
> rcu_read_lock();
>
> wcid = rcu_dereference(dev->mt76.wcid[wcidx]);
> - if (!wcid)
> + if (!wcid || !wcid->sta)
> goto out;
>
> - mt7915_mac_add_txs_skb(dev, wcid, pid, txs_data);
> + msta = container_of(wcid, struct mt7915_sta, wcid);
>
> - if (!wcid->sta)
> - goto out;
> + mt7915_mac_add_txs_skb(dev, wcid, pid, txs_data, &msta->stats);

it seems to me here we are changing the behaviour since
mt7915_mac_add_txs_skb() is run even with wcid->sta = false

Regards,
Lorenzo

>
> - 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 a3c78365db23..ff944d1cf527 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
>


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