mt76: mt7921: add per-vif counters in ethtool
authorLorenzo Bianconi <lorenzo@kernel.org>
Tue, 19 Oct 2021 10:12:32 +0000 (12:12 +0200)
committerFelix Fietkau <nbd@nbd.name>
Wed, 20 Oct 2021 08:37:03 +0000 (10:37 +0200)
Similar to mt7915 driver, add per-vif tx counters in ethtool.

Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: Felix Fietkau <nbd@nbd.name>
drivers/net/wireless/mediatek/mt76/mt7921/main.c

index 575f23d9ec525ed36aee8778a67ae67c5649f785..35a490c049e903e96c79bba13f5407f9bfe43d18 100644 (file)
@@ -902,7 +902,33 @@ static const char mt7921_gstrings_stats[][ETH_GSTRING_LEN] = {
        "rx_mpdu_cnt",
        "rx_ampdu_cnt",
        "rx_ampdu_bytes_cnt",
-       "rx_ba_cnt"
+       "rx_ba_cnt",
+       /* per vif counters */
+       "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",
 };
 
 static void
@@ -922,13 +948,30 @@ mt7921_get_et_sset_count(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
        return sset == ETH_SS_STATS ? ARRAY_SIZE(mt7921_gstrings_stats) : 0;
 }
 
+static void
+mt7921_ethtool_worker(void *wi_data, struct ieee80211_sta *sta)
+{
+       struct mt7921_sta *msta = (struct mt7921_sta *)sta->drv_priv;
+       struct mt76_ethtool_worker_info *wi = wi_data;
+
+       if (msta->vif->mt76.idx != wi->idx)
+               return;
+
+       mt76_ethtool_worker(wi, &msta->stats);
+}
+
 static
 void mt7921_get_et_stats(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
                         struct ethtool_stats *stats, u64 *data)
 {
+       struct mt7921_vif *mvif = (struct mt7921_vif *)vif->drv_priv;
        struct mt7921_phy *phy = mt7921_hw_phy(hw);
        struct mt7921_dev *dev = phy->dev;
        struct mib_stats *mib = &phy->mib;
+       struct mt76_ethtool_worker_info wi = {
+               .data = data,
+               .idx = mvif->mt76.idx,
+       };
        int i, ei = 0;
 
        mt7921_mutex_acquire(dev);
@@ -967,8 +1010,16 @@ void mt7921_get_et_stats(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
        data[ei++] = mib->rx_ampdu_bytes_cnt;
        data[ei++] = mib->rx_ba_cnt;
 
+       /* Add values for all stations owned by this vif */
+       wi.initial_stat_idx = ei;
+       ieee80211_iterate_stations_atomic(hw, mt7921_ethtool_worker, &wi);
+
        mt7921_mutex_release(dev);
 
+       if (!wi.sta_count)
+               return;
+
+       ei += wi.worker_stat_count;
        if (ei != ARRAY_SIZE(mt7921_gstrings_stats))
                dev_err(dev->mt76.dev, "ei: %d  SSTATS_LEN: %lu",
                        ei, ARRAY_SIZE(mt7921_gstrings_stats));