@@ -738,7 +738,9 @@ bool mt76_connac2_mac_add_txs_skb(struct mt76_dev *dev, struct mt76_wcid *wcid,
info->status.ampdu_ack_len = !noacked;
info->status.rates[0].idx = -1;
- wcid->stats.tx_failed += noacked;
+ /* avoid double counting if dev supports txfree event */
+ if (is_mt7921(dev))
+ wcid->stats.tx_failed += noacked;
mt76_connac2_mac_fill_txs(dev, wcid, txs_data);
mt76_tx_status_skb_done(dev, skb, &list);
@@ -951,6 +951,7 @@ mt7915_mac_tx_free(struct mt7915_dev *dev, void *data, int len)
struct mt76_dev *mdev = &dev->mt76;
struct mt76_txwi_cache *txwi;
struct ieee80211_sta *sta = NULL;
+ struct mt76_wcid *wcid = NULL;
LIST_HEAD(free_list);
void *end = data + len;
bool v3, wake = false;
@@ -977,7 +978,6 @@ mt7915_mac_tx_free(struct mt7915_dev *dev, void *data, int len)
info = le32_to_cpu(*cur_info);
if (info & MT_TX_FREE_PAIR) {
struct mt7915_sta *msta;
- struct mt76_wcid *wcid;
u16 idx;
idx = FIELD_GET(MT_TX_FREE_WLAN_ID, info);
@@ -994,7 +994,25 @@ mt7915_mac_tx_free(struct mt7915_dev *dev, void *data, int len)
continue;
}
- if (v3 && (info & MT_TX_FREE_MPDU_HEADER))
+ if (!mtk_wed_device_active(&mdev->mmio.wed) && wcid) {
+ u32 tx_retries = 0, tx_failed = 0;
+
+ if (v3 && (info & MT_TX_FREE_MPDU_HEADER_V3)) {
+ tx_retries =
+ FIELD_GET(MT_TX_FREE_COUNT_V3, info) - 1;
+ tx_failed = tx_retries +
+ !!FIELD_GET(MT_TX_FREE_STAT_V3, info);
+ } else if (!v3 && (info & MT_TX_FREE_MPDU_HEADER)) {
+ tx_retries =
+ FIELD_GET(MT_TX_FREE_COUNT, info) - 1;
+ tx_failed = tx_retries +
+ !!FIELD_GET(MT_TX_FREE_STAT, info);
+ }
+ wcid->stats.tx_retries += tx_retries;
+ wcid->stats.tx_failed += tx_failed;
+ }
+
+ if (v3 && (info & MT_TX_FREE_MPDU_HEADER_V3))
continue;
for (i = 0; i < 1 + v3; i++) {
@@ -9,7 +9,12 @@
#define MT_TX_FREE_VER GENMASK(18, 16)
#define MT_TX_FREE_MSDU_CNT_V0 GENMASK(6, 0)
/* 0: success, others: dropped */
-#define MT_TX_FREE_MPDU_HEADER BIT(30)
+#define MT_TX_FREE_COUNT GENMASK(12, 0)
+#define MT_TX_FREE_COUNT_V3 GENMASK(27, 24)
+#define MT_TX_FREE_STAT GENMASK(14, 13)
+#define MT_TX_FREE_STAT_V3 GENMASK(29, 28)
+#define MT_TX_FREE_MPDU_HEADER BIT(15)
+#define MT_TX_FREE_MPDU_HEADER_V3 BIT(30)
#define MT_TX_FREE_MSDU_ID_V3 GENMASK(14, 0)
#define MT_TXS5_F0_FINAL_MPDU BIT(31)
@@ -1046,12 +1046,6 @@ static void mt7915_sta_statistics(struct ieee80211_hw *hw,
sinfo->tx_packets = msta->wcid.stats.tx_packets;
sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_PACKETS);
- sinfo->tx_failed = msta->wcid.stats.tx_failed;
- sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_FAILED);
-
- sinfo->tx_retries = msta->wcid.stats.tx_retries;
- sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_RETRIES);
-
if (mtk_wed_get_rx_capa(&phy->dev->mt76.mmio.wed)) {
sinfo->rx_bytes = msta->wcid.stats.rx_bytes;
sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_BYTES64);
@@ -1061,6 +1055,12 @@ static void mt7915_sta_statistics(struct ieee80211_hw *hw,
}
}
+ sinfo->tx_failed = msta->wcid.stats.tx_failed;
+ sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_FAILED);
+
+ sinfo->tx_retries = msta->wcid.stats.tx_retries;
+ sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_RETRIES);
+
sinfo->ack_signal = (s8)msta->ack_signal;
sinfo->filled |= BIT_ULL(NL80211_STA_INFO_ACK_SIGNAL);