> From: Ben Greear > > 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 > --- > 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 >