All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 1/8] mt76 - mt7915: Add ethtool stats support.
@ 2021-07-22 20:24 greearb
  2021-07-22 20:24 ` [PATCH v3 2/8] mt76 - mt7915: Add tx stats gathered from tx-status callbacks greearb
                   ` (7 more replies)
  0 siblings, 8 replies; 12+ messages in thread
From: greearb @ 2021-07-22 20:24 UTC (permalink / raw)
  To: linux-wireless; +Cc: Ben Greear

From: Ben Greear <greearb@candelatech.com>

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 <greearb@candelatech.com>
---
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


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v3 2/8] mt76 - mt7915: Add tx stats gathered from tx-status callbacks.
  2021-07-22 20:24 [PATCH v3 1/8] mt76 - mt7915: Add ethtool stats support greearb
@ 2021-07-22 20:24 ` greearb
  2021-07-22 21:45   ` Lorenzo Bianconi
  2021-07-22 20:24 ` [PATCH v3 3/8] mt76 - mt7915: Add some per-station tx stats to ethtool greearb
                   ` (6 subsequent siblings)
  7 siblings, 1 reply; 12+ messages in thread
From: greearb @ 2021-07-22 20:24 UTC (permalink / raw)
  To: linux-wireless; +Cc: Ben Greear

From: Ben Greear <greearb@candelatech.com>

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 <greearb@candelatech.com>
---
 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


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v3 3/8] mt76 - mt7915: Add some per-station tx stats to ethtool.
  2021-07-22 20:24 [PATCH v3 1/8] mt76 - mt7915: Add ethtool stats support greearb
  2021-07-22 20:24 ` [PATCH v3 2/8] mt76 - mt7915: Add tx stats gathered from tx-status callbacks greearb
@ 2021-07-22 20:24 ` greearb
  2021-07-22 21:46   ` Lorenzo Bianconi
  2021-07-22 20:25 ` [PATCH v3 4/8] mt76 - mt7915: Add tx mu/su counters to mib greearb
                   ` (5 subsequent siblings)
  7 siblings, 1 reply; 12+ messages in thread
From: greearb @ 2021-07-22 20:24 UTC (permalink / raw)
  To: linux-wireless; +Cc: Ben Greear

From: Ben Greear <greearb@candelatech.com>

The tx status callback is not called for every frame, so
those specific counters under-count, but at least they give
some idea of what is going on.

Signed-off-by: Ben Greear <greearb@candelatech.com>
---
 .../wireless/mediatek/mt76/mt7915/debugfs.c   | 116 +++++++++++++++++-
 1 file changed, 110 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c b/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c
index 469028d641c7..ad400ddf36c3 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c
@@ -425,6 +425,35 @@ static const char mt7915_gstrings_stats[][ETH_GSTRING_LEN] = {
 	"tx_msdu_pack_6",
 	"tx_msdu_pack_7",
 	"tx_msdu_pack_8",
+	/* per vif counters */
+	"v_tx_mpdu_attempts",
+	"v_tx_mpdu_fail",
+	"v_tx_mpdu_retry",
+	"v_tx_mode_cck",
+	"v_tx_mode_ofdm",
+	"v_tx_mode_ht",
+	"v_tx_mode_ht_gf",
+	"v_tx_mode_vht",
+	"v_tx_mode_he_su",
+	"v_tx_mode_he_ext_su",
+	"v_tx_mode_he_tb",
+	"v_tx_mode_he_mu",
+	"v_tx_bw_20",
+	"v_tx_bw_40",
+	"v_tx_bw_80",
+	"v_tx_bw_160",
+	"v_tx_mcs_0",
+	"v_tx_mcs_1",
+	"v_tx_mcs_2",
+	"v_tx_mcs_3",
+	"v_tx_mcs_4",
+	"v_tx_mcs_5",
+	"v_tx_mcs_6",
+	"v_tx_mcs_7",
+	"v_tx_mcs_8",
+	"v_tx_mcs_9",
+	"v_tx_mcs_10",
+	"v_tx_mcs_11",
 };
 
 #define MT7915_SSTATS_LEN ARRAY_SIZE(mt7915_gstrings_stats)
@@ -454,14 +483,15 @@ void mt7915_debug_get_et_stats(struct ieee80211_hw *hw,
 {
 	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?
-	 */
+	struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;
+	struct mt76_wcid *wcid;
+	struct mt7915_sta *msta;
+	struct mt7915_sta_stats *mstats;
+	bool found_sta = false;
 
 	/* See mt7915_ampdu_stat_read_phy, etc */
 	bool ext_phy = phy != &dev->phy;
-	int i, n, cnt;
+	int i, j, n, cnt, next_ei;
 	int ei = 0;
 
 	if (!phy)
@@ -515,6 +545,80 @@ void mt7915_debug_get_et_stats(struct ieee80211_hw *hw,
 	for (i = 0; i < 8; i++)
 		data[ei++] = mt76_rr(dev,  MT_PLE_AMSDU_PACK_MSDU_CNT(i));
 
-	WARN_ON(ei != MT7915_SSTATS_LEN);
+	/* Add values for all stations owned by this vif */
+
+	/* See mt76_get_min_avr_rssi for example of how to find all sta
+	 * for a vif
+	 */
+	local_bh_disable();
+	rcu_read_lock();
+
+	next_ei = ei;
+
+	for (i = 0; i < ARRAY_SIZE(dev->mt76.wcid_mask); i++) {
+		u32 mask = dev->mt76.wcid_mask[i];
+		u32 phy_mask = dev->mt76.wcid_phy_mask[i];
+		int q;
+
+		if (!mask)
+			continue;
+
+		for (j = i * 32; mask; j++, mask >>= 1, phy_mask >>= 1) {
+			if (!(mask & 1))
+				continue;
+
+			if (!!(phy_mask & 1) != ext_phy)
+				continue;
+
+			wcid = rcu_dereference(dev->mt76.wcid[j]);
+			if (!wcid)
+				continue;
+
+			msta = container_of(wcid, struct mt7915_sta, wcid);
+
+			if (msta->vif != mvif)
+				continue;
+
+			ei = next_ei;
+			mstats = &msta->stats;
+			data[ei++] += mstats->tx_mpdu_attempts;
+			data[ei++] += mstats->tx_mpdu_fail;
+			data[ei++] += mstats->tx_mpdu_retry;
+			data[ei++] += mstats->tx_mode[MT_PHY_TYPE_CCK];
+			data[ei++] += mstats->tx_mode[MT_PHY_TYPE_OFDM];
+			data[ei++] += mstats->tx_mode[MT_PHY_TYPE_HT];
+			data[ei++] += mstats->tx_mode[MT_PHY_TYPE_HT_GF];
+			data[ei++] += mstats->tx_mode[MT_PHY_TYPE_VHT];
+			data[ei++] += mstats->tx_mode[MT_PHY_TYPE_HE_SU];
+			data[ei++] += mstats->tx_mode[MT_PHY_TYPE_HE_EXT_SU];
+			data[ei++] += mstats->tx_mode[MT_PHY_TYPE_HE_TB];
+			data[ei++] += mstats->tx_mode[MT_PHY_TYPE_HE_MU];
+
+			for (q = 0; q < ARRAY_SIZE(mstats->tx_bw); q++)
+				data[ei++] += mstats->tx_bw[q];
+
+			for (q = 0; q < 12; q++)
+				data[ei++] += mstats->tx_mcs[q];
+			found_sta = true;
+		}
+	}
+
+	rcu_read_unlock();
+	local_bh_enable();
+
+	/* If we have no stations above, then we will not have filled out
+	 * the STA stats.  Zero those stats.
+	 */
+	if (!found_sta) {
+		int q;
+
+		for (q = 0; q < 28; q++)
+			data[ei++] = 0;
+	}
+
+	if (ei != MT7915_SSTATS_LEN) {
+		pr_err("ei: %d  MT7915_SSTATS_LEN: %d", ei, (int)(MT7915_SSTATS_LEN));
+		WARN_ON_ONCE(ei != MT7915_SSTATS_LEN);
+	}
 }
 
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v3 4/8] mt76 - mt7915: Add tx mu/su counters to mib
  2021-07-22 20:24 [PATCH v3 1/8] mt76 - mt7915: Add ethtool stats support greearb
  2021-07-22 20:24 ` [PATCH v3 2/8] mt76 - mt7915: Add tx stats gathered from tx-status callbacks greearb
  2021-07-22 20:24 ` [PATCH v3 3/8] mt76 - mt7915: Add some per-station tx stats to ethtool greearb
@ 2021-07-22 20:25 ` greearb
  2021-07-22 21:48   ` Lorenzo Bianconi
  2021-07-22 20:25 ` [PATCH v3 5/8] mt76 - mt7915: Move more tx-bf stats " greearb
                   ` (4 subsequent siblings)
  7 siblings, 1 reply; 12+ messages in thread
From: greearb @ 2021-07-22 20:25 UTC (permalink / raw)
  To: linux-wireless; +Cc: Ben Greear

From: Ben Greear <greearb@candelatech.com>

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 <greearb@candelatech.com>
---
 .../wireless/mediatek/mt76/mt7915/debugfs.c   | 33 ++++++++-----------
 .../net/wireless/mediatek/mt76/mt7915/mac.c   | 13 +++++++-
 .../wireless/mediatek/mt76/mt7915/mt7915.h    |  4 +++
 3 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 ad400ddf36c3..759899c44583 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_successful_mpdu_cnt);
+	seq_printf(s, "Tx single-user successful MPDU counts: %d\n",
+		   mib->tx_su_successful_mpdu_cnt);
 
 	seq_puts(s, "\n");
 }
@@ -488,6 +487,7 @@ void mt7915_debug_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;
@@ -527,17 +527,10 @@ void mt7915_debug_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_successful_mpdu_cnt;
+	data[ei++] = mib->tx_su_successful_mpdu_cnt;
 
 	/* TODO:  External phy too?? */
 
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
index 3a10e14fbd50..23540ba5da97 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
@@ -1880,10 +1880,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_successful_mpdu_cnt += cnt;
+
+	cnt = mt76_rr(dev, MT_MIB_DR11(ext_phy));
+	mib->tx_su_successful_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/mt7915.h b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
index ff944d1cf527..c5d0f2331b6f 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_successful_mpdu_cnt;
+	u32 tx_su_successful_mpdu_cnt;
 	/* Add more stats here, updated from mac_update_stats */
 };
 
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v3 5/8] mt76 - mt7915: Move more tx-bf stats to mib.
  2021-07-22 20:24 [PATCH v3 1/8] mt76 - mt7915: Add ethtool stats support greearb
                   ` (2 preceding siblings ...)
  2021-07-22 20:25 ` [PATCH v3 4/8] mt76 - mt7915: Add tx mu/su counters to mib greearb
@ 2021-07-22 20:25 ` greearb
  2021-07-22 20:25 ` [PATCH v3 6/8] mt76 - mt7915: Fix he_mcs capabilities for 160mhz greearb
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 12+ messages in thread
From: greearb @ 2021-07-22 20:25 UTC (permalink / raw)
  To: linux-wireless; +Cc: Ben Greear

From: Ben Greear <greearb@candelatech.com>

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 <greearb@candelatech.com>
---
 .../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


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v3 6/8] mt76 - mt7915: Fix he_mcs capabilities for 160mhz.
  2021-07-22 20:24 [PATCH v3 1/8] mt76 - mt7915: Add ethtool stats support greearb
                   ` (3 preceding siblings ...)
  2021-07-22 20:25 ` [PATCH v3 5/8] mt76 - mt7915: Move more tx-bf stats " greearb
@ 2021-07-22 20:25 ` greearb
  2021-07-22 20:25 ` [PATCH v3 7/8] mt76 - mt7915: Add more MIB registers greearb
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 12+ messages in thread
From: greearb @ 2021-07-22 20:25 UTC (permalink / raw)
  To: linux-wireless; +Cc: Ben Greear

From: Ben Greear <greearb@candelatech.com>

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 <greearb@candelatech.com>
---
 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


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v3 7/8] mt76 - mt7915: Add more MIB registers.
  2021-07-22 20:24 [PATCH v3 1/8] mt76 - mt7915: Add ethtool stats support greearb
                   ` (4 preceding siblings ...)
  2021-07-22 20:25 ` [PATCH v3 6/8] mt76 - mt7915: Fix he_mcs capabilities for 160mhz greearb
@ 2021-07-22 20:25 ` greearb
  2021-07-22 20:25 ` [PATCH v3 8/8] mt76 - mt7915: Add mib counters to ethtool stats greearb
  2021-07-22 20:52 ` [PATCH v3 1/8] mt76 - mt7915: Add ethtool stats support Lorenzo Bianconi
  7 siblings, 0 replies; 12+ messages in thread
From: greearb @ 2021-07-22 20:25 UTC (permalink / raw)
  To: linux-wireless; +Cc: Ben Greear

From: Ben Greear <greearb@candelatech.com>

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 <greearb@candelatech.com>
---
 .../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 abde1b52ad71..cb6d9d2d4e06 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
@@ -1884,6 +1884,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 29a39c24633a..fcc5cd60cfc8 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


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v3 8/8] mt76 - mt7915:  Add mib counters to ethtool stats.
  2021-07-22 20:24 [PATCH v3 1/8] mt76 - mt7915: Add ethtool stats support greearb
                   ` (5 preceding siblings ...)
  2021-07-22 20:25 ` [PATCH v3 7/8] mt76 - mt7915: Add more MIB registers greearb
@ 2021-07-22 20:25 ` greearb
  2021-07-22 20:52 ` [PATCH v3 1/8] mt76 - mt7915: Add ethtool stats support Lorenzo Bianconi
  7 siblings, 0 replies; 12+ messages in thread
From: greearb @ 2021-07-22 20:25 UTC (permalink / raw)
  To: linux-wireless; +Cc: Ben Greear

From: Ben Greear <greearb@candelatech.com>

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

Signed-off-by: Ben Greear <greearb@candelatech.com>
---
 .../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


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: [PATCH v3 1/8] mt76 - mt7915: Add ethtool stats support.
  2021-07-22 20:24 [PATCH v3 1/8] mt76 - mt7915: Add ethtool stats support greearb
                   ` (6 preceding siblings ...)
  2021-07-22 20:25 ` [PATCH v3 8/8] mt76 - mt7915: Add mib counters to ethtool stats greearb
@ 2021-07-22 20:52 ` Lorenzo Bianconi
  7 siblings, 0 replies; 12+ messages in thread
From: Lorenzo Bianconi @ 2021-07-22 20:52 UTC (permalink / raw)
  To: greearb; +Cc: linux-wireless

[-- Attachment #1: Type: text/plain, Size: 7026 bytes --]

> From: Ben Greear <greearb@candelatech.com>
> 
> 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 <greearb@candelatech.com>
> ---
> 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
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v3 2/8] mt76 - mt7915: Add tx stats gathered from tx-status callbacks.
  2021-07-22 20:24 ` [PATCH v3 2/8] mt76 - mt7915: Add tx stats gathered from tx-status callbacks greearb
@ 2021-07-22 21:45   ` Lorenzo Bianconi
  0 siblings, 0 replies; 12+ messages in thread
From: Lorenzo Bianconi @ 2021-07-22 21:45 UTC (permalink / raw)
  To: greearb; +Cc: linux-wireless

[-- Attachment #1: Type: text/plain, Size: 6134 bytes --]

> From: Ben Greear <greearb@candelatech.com>
> 
> 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 <greearb@candelatech.com>
> ---
>  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/20210720130014.23572-2-shayne.chen@mediatek.com/

> +
> +	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
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v3 3/8] mt76 - mt7915: Add some per-station tx stats to ethtool.
  2021-07-22 20:24 ` [PATCH v3 3/8] mt76 - mt7915: Add some per-station tx stats to ethtool greearb
@ 2021-07-22 21:46   ` Lorenzo Bianconi
  0 siblings, 0 replies; 12+ messages in thread
From: Lorenzo Bianconi @ 2021-07-22 21:46 UTC (permalink / raw)
  To: greearb; +Cc: linux-wireless

[-- Attachment #1: Type: text/plain, Size: 4729 bytes --]

> From: Ben Greear <greearb@candelatech.com>
> 
> The tx status callback is not called for every frame, so
> those specific counters under-count, but at least they give
> some idea of what is going on.
> 
> Signed-off-by: Ben Greear <greearb@candelatech.com>
> ---
>  .../wireless/mediatek/mt76/mt7915/debugfs.c   | 116 +++++++++++++++++-
>  1 file changed, 110 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c b/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c
> index 469028d641c7..ad400ddf36c3 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c
> +++ b/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c
> @@ -425,6 +425,35 @@ static const char mt7915_gstrings_stats[][ETH_GSTRING_LEN] = {
>  	"tx_msdu_pack_6",
>  	"tx_msdu_pack_7",
>  	"tx_msdu_pack_8",
> +	/* per vif counters */
> +	"v_tx_mpdu_attempts",
> +	"v_tx_mpdu_fail",
> +	"v_tx_mpdu_retry",
> +	"v_tx_mode_cck",
> +	"v_tx_mode_ofdm",
> +	"v_tx_mode_ht",
> +	"v_tx_mode_ht_gf",
> +	"v_tx_mode_vht",
> +	"v_tx_mode_he_su",
> +	"v_tx_mode_he_ext_su",
> +	"v_tx_mode_he_tb",
> +	"v_tx_mode_he_mu",
> +	"v_tx_bw_20",
> +	"v_tx_bw_40",
> +	"v_tx_bw_80",
> +	"v_tx_bw_160",
> +	"v_tx_mcs_0",
> +	"v_tx_mcs_1",
> +	"v_tx_mcs_2",
> +	"v_tx_mcs_3",
> +	"v_tx_mcs_4",
> +	"v_tx_mcs_5",
> +	"v_tx_mcs_6",
> +	"v_tx_mcs_7",
> +	"v_tx_mcs_8",
> +	"v_tx_mcs_9",
> +	"v_tx_mcs_10",
> +	"v_tx_mcs_11",
>  };
>  
>  #define MT7915_SSTATS_LEN ARRAY_SIZE(mt7915_gstrings_stats)
> @@ -454,14 +483,15 @@ void mt7915_debug_get_et_stats(struct ieee80211_hw *hw,
>  {
>  	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?
> -	 */
> +	struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;
> +	struct mt76_wcid *wcid;
> +	struct mt7915_sta *msta;
> +	struct mt7915_sta_stats *mstats;
> +	bool found_sta = false;
>  
>  	/* See mt7915_ampdu_stat_read_phy, etc */
>  	bool ext_phy = phy != &dev->phy;
> -	int i, n, cnt;
> +	int i, j, n, cnt, next_ei;
>  	int ei = 0;
>  
>  	if (!phy)
> @@ -515,6 +545,80 @@ void mt7915_debug_get_et_stats(struct ieee80211_hw *hw,
>  	for (i = 0; i < 8; i++)
>  		data[ei++] = mt76_rr(dev,  MT_PLE_AMSDU_PACK_MSDU_CNT(i));
>  
> -	WARN_ON(ei != MT7915_SSTATS_LEN);
> +	/* Add values for all stations owned by this vif */
> +
> +	/* See mt76_get_min_avr_rssi for example of how to find all sta
> +	 * for a vif
> +	 */
> +	local_bh_disable();
> +	rcu_read_lock();
> +
> +	next_ei = ei;
> +
> +	for (i = 0; i < ARRAY_SIZE(dev->mt76.wcid_mask); i++) {
> +		u32 mask = dev->mt76.wcid_mask[i];
> +		u32 phy_mask = dev->mt76.wcid_phy_mask[i];
> +		int q;

can we use ieee80211_iterate_stations_atomic() here?

Regards,
Lorenzo

> +
> +		if (!mask)
> +			continue;
> +
> +		for (j = i * 32; mask; j++, mask >>= 1, phy_mask >>= 1) {
> +			if (!(mask & 1))
> +				continue;
> +
> +			if (!!(phy_mask & 1) != ext_phy)
> +				continue;
> +
> +			wcid = rcu_dereference(dev->mt76.wcid[j]);
> +			if (!wcid)
> +				continue;
> +
> +			msta = container_of(wcid, struct mt7915_sta, wcid);
> +
> +			if (msta->vif != mvif)
> +				continue;
> +
> +			ei = next_ei;
> +			mstats = &msta->stats;
> +			data[ei++] += mstats->tx_mpdu_attempts;
> +			data[ei++] += mstats->tx_mpdu_fail;
> +			data[ei++] += mstats->tx_mpdu_retry;
> +			data[ei++] += mstats->tx_mode[MT_PHY_TYPE_CCK];
> +			data[ei++] += mstats->tx_mode[MT_PHY_TYPE_OFDM];
> +			data[ei++] += mstats->tx_mode[MT_PHY_TYPE_HT];
> +			data[ei++] += mstats->tx_mode[MT_PHY_TYPE_HT_GF];
> +			data[ei++] += mstats->tx_mode[MT_PHY_TYPE_VHT];
> +			data[ei++] += mstats->tx_mode[MT_PHY_TYPE_HE_SU];
> +			data[ei++] += mstats->tx_mode[MT_PHY_TYPE_HE_EXT_SU];
> +			data[ei++] += mstats->tx_mode[MT_PHY_TYPE_HE_TB];
> +			data[ei++] += mstats->tx_mode[MT_PHY_TYPE_HE_MU];
> +
> +			for (q = 0; q < ARRAY_SIZE(mstats->tx_bw); q++)
> +				data[ei++] += mstats->tx_bw[q];
> +
> +			for (q = 0; q < 12; q++)
> +				data[ei++] += mstats->tx_mcs[q];
> +			found_sta = true;
> +		}
> +	}
> +
> +	rcu_read_unlock();
> +	local_bh_enable();
> +
> +	/* If we have no stations above, then we will not have filled out
> +	 * the STA stats.  Zero those stats.
> +	 */
> +	if (!found_sta) {
> +		int q;
> +
> +		for (q = 0; q < 28; q++)
> +			data[ei++] = 0;
> +	}
> +
> +	if (ei != MT7915_SSTATS_LEN) {
> +		pr_err("ei: %d  MT7915_SSTATS_LEN: %d", ei, (int)(MT7915_SSTATS_LEN));
> +		WARN_ON_ONCE(ei != MT7915_SSTATS_LEN);
> +	}
>  }
>  
> -- 
> 2.20.1
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v3 4/8] mt76 - mt7915: Add tx mu/su counters to mib
  2021-07-22 20:25 ` [PATCH v3 4/8] mt76 - mt7915: Add tx mu/su counters to mib greearb
@ 2021-07-22 21:48   ` Lorenzo Bianconi
  0 siblings, 0 replies; 12+ messages in thread
From: Lorenzo Bianconi @ 2021-07-22 21:48 UTC (permalink / raw)
  To: greearb; +Cc: linux-wireless

[-- Attachment #1: Type: text/plain, Size: 5100 bytes --]

On Jul 22, greearb@candelatech.com wrote:
> From: Ben Greear <greearb@candelatech.com>
> 
> 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 <greearb@candelatech.com>
> ---
>  .../wireless/mediatek/mt76/mt7915/debugfs.c   | 33 ++++++++-----------
>  .../net/wireless/mediatek/mt76/mt7915/mac.c   | 13 +++++++-
>  .../wireless/mediatek/mt76/mt7915/mt7915.h    |  4 +++
>  3 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 ad400ddf36c3..759899c44583 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_successful_mpdu_cnt);
> +	seq_printf(s, "Tx single-user successful MPDU counts: %d\n",
> +		   mib->tx_su_successful_mpdu_cnt);
>  
>  	seq_puts(s, "\n");
>  }
> @@ -488,6 +487,7 @@ void mt7915_debug_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;
> @@ -527,17 +527,10 @@ void mt7915_debug_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_successful_mpdu_cnt;
> +	data[ei++] = mib->tx_su_successful_mpdu_cnt;
>  
>  	/* TODO:  External phy too?? */
>  
> diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
> index 3a10e14fbd50..23540ba5da97 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
> +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
> @@ -1880,10 +1880,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_successful_mpdu_cnt += cnt;
> +
> +	cnt = mt76_rr(dev, MT_MIB_DR11(ext_phy));
> +	mib->tx_su_successful_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/mt7915.h b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
> index ff944d1cf527..c5d0f2331b6f 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_successful_mpdu_cnt;
> +	u32 tx_su_successful_mpdu_cnt;

nit:
s/tx_mu_successful*/tx_mu_acked*/

>  	/* Add more stats here, updated from mac_update_stats */
>  };
>  
> -- 
> 2.20.1
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2021-07-22 21:48 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-07-22 20:24 [PATCH v3 1/8] mt76 - mt7915: Add ethtool stats support greearb
2021-07-22 20:24 ` [PATCH v3 2/8] mt76 - mt7915: Add tx stats gathered from tx-status callbacks greearb
2021-07-22 21:45   ` Lorenzo Bianconi
2021-07-22 20:24 ` [PATCH v3 3/8] mt76 - mt7915: Add some per-station tx stats to ethtool greearb
2021-07-22 21:46   ` Lorenzo Bianconi
2021-07-22 20:25 ` [PATCH v3 4/8] mt76 - mt7915: Add tx mu/su counters to mib greearb
2021-07-22 21:48   ` Lorenzo Bianconi
2021-07-22 20:25 ` [PATCH v3 5/8] mt76 - mt7915: Move more tx-bf stats " greearb
2021-07-22 20:25 ` [PATCH v3 6/8] mt76 - mt7915: Fix he_mcs capabilities for 160mhz greearb
2021-07-22 20:25 ` [PATCH v3 7/8] mt76 - mt7915: Add more MIB registers greearb
2021-07-22 20:25 ` [PATCH v3 8/8] mt76 - mt7915: Add mib counters to ethtool stats greearb
2021-07-22 20:52 ` [PATCH v3 1/8] mt76 - mt7915: Add ethtool stats support Lorenzo Bianconi

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.