blob: e99536add14b196ddb965c7608ad16a09b6e47f9 [file] [log] [blame]
developerfb1448d2022-08-02 17:08:37 -07001From c00e4e966cec137840f38cd0c7abf3f3237e9ea2 Mon Sep 17 00:00:00 2001
2From: Yi-Chia Hsieh <Yi-Chia.Hsieh@mediatek.com>
3Date: Thu, 21 Jul 2022 10:56:09 -0700
4Subject: [PATCH] mt76: mt7915: add statistic for H/W Tx Path
5
6Set PPDU_TXS2H_EN_B0/B1 to get PPDU txs.
7Add MT_PACKET_ID_WED for PPDU txs, and change MT_PACKET_ID_FIRST to 3
8to differentiate. We also need do byte cnt and pkt cnt for S/W path since
9we report it directly from mt7915_sta_statistics.
10
11---
12 mt76.h | 49 ++++++++++++++++-------------
13 mt76_connac.h | 5 +--
14 mt76_connac2_mac.h | 14 +++++++++
15 mt76_connac_mac.c | 77 +++++++++++++++++++++++++++++-----------------
16 mt7915/mac.c | 12 ++++----
17 mt7915/main.c | 16 +++++++++-
18 mt7915/mmio.c | 22 +++++++++++++
19 mt7915/mt7915.h | 2 --
20 mt7915/regs.h | 4 +++
21 mt7921/mt7921.h | 1 -
22 10 files changed, 141 insertions(+), 61 deletions(-)
23
24diff --git a/mt76.h b/mt76.h
25index 9162213..720a419 100644
26--- a/mt76.h
27+++ b/mt76.h
28@@ -267,6 +267,30 @@ DECLARE_EWMA(signal, 10, 8);
29 #define MT_WCID_TX_INFO_TXPWR_ADJ GENMASK(25, 18)
30 #define MT_WCID_TX_INFO_SET BIT(31)
31
32+enum mt76_phy_type {
33+ MT_PHY_TYPE_CCK,
34+ MT_PHY_TYPE_OFDM,
35+ MT_PHY_TYPE_HT,
36+ MT_PHY_TYPE_HT_GF,
37+ MT_PHY_TYPE_VHT,
38+ MT_PHY_TYPE_HE_SU = 8,
39+ MT_PHY_TYPE_HE_EXT_SU,
40+ MT_PHY_TYPE_HE_TB,
41+ MT_PHY_TYPE_HE_MU,
42+ __MT_PHY_TYPE_HE_MAX,
43+};
44+
45+struct mt76_sta_stats {
46+ u64 tx_mode[__MT_PHY_TYPE_HE_MAX];
47+ u64 tx_bw[4]; /* 20, 40, 80, 160 */
48+ u64 tx_nss[4]; /* 1, 2, 3, 4 */
49+ u64 tx_mcs[16]; /* mcs idx */
50+ u64 tx_bytes;
51+ u32 tx_packets;
52+ u32 tx_retries;
53+ u32 tx_failed;
54+};
55+
56 struct mt76_wcid {
57 struct mt76_rx_tid __rcu *aggr[IEEE80211_NUM_TIDS];
58
59@@ -295,6 +319,8 @@ struct mt76_wcid {
60
61 struct list_head list;
62 struct idr pktid;
63+
64+ struct mt76_sta_stats stats;
65 };
66
67 struct mt76_txq {
68@@ -341,7 +367,8 @@ struct mt76_rx_tid {
69 #define MT_PACKET_ID_MASK GENMASK(6, 0)
70 #define MT_PACKET_ID_NO_ACK 0
71 #define MT_PACKET_ID_NO_SKB 1
72-#define MT_PACKET_ID_FIRST 2
73+#define MT_PACKET_ID_WED 2
74+#define MT_PACKET_ID_FIRST 3
75 #define MT_PACKET_ID_HAS_RATE BIT(7)
76 /* This is timer for when to give up when waiting for TXS callback,
77 * with starting time being the time at which the DMA_DONE callback
78@@ -861,26 +888,6 @@ struct mt76_power_limits {
79 s8 ru[7][12];
80 };
81
82-enum mt76_phy_type {
83- MT_PHY_TYPE_CCK,
84- MT_PHY_TYPE_OFDM,
85- MT_PHY_TYPE_HT,
86- MT_PHY_TYPE_HT_GF,
87- MT_PHY_TYPE_VHT,
88- MT_PHY_TYPE_HE_SU = 8,
89- MT_PHY_TYPE_HE_EXT_SU,
90- MT_PHY_TYPE_HE_TB,
91- MT_PHY_TYPE_HE_MU,
92- __MT_PHY_TYPE_HE_MAX,
93-};
94-
95-struct mt76_sta_stats {
96- u64 tx_mode[__MT_PHY_TYPE_HE_MAX];
97- u64 tx_bw[4]; /* 20, 40, 80, 160 */
98- u64 tx_nss[4]; /* 1, 2, 3, 4 */
99- u64 tx_mcs[16]; /* mcs idx */
100-};
101-
102 struct mt76_ethtool_worker_info {
103 u64 *data;
104 int idx;
105diff --git a/mt76_connac.h b/mt76_connac.h
106index c8d8680..8f78d12 100644
107--- a/mt76_connac.h
108+++ b/mt76_connac.h
109@@ -352,9 +352,10 @@ void mt76_connac2_mac_write_txwi(struct mt76_dev *dev, __le32 *txwi,
110 struct sk_buff *skb, struct mt76_wcid *wcid,
111 struct ieee80211_key_conf *key, int pid,
112 enum mt76_txq_id qid, u32 changed);
113+bool mt76_connac2_mac_fill_txs(struct mt76_dev *dev, struct mt76_wcid *wcid,
114+ __le32 *txs_data, struct mt76_sta_stats *stats);
115 bool mt76_connac2_mac_add_txs_skb(struct mt76_dev *dev, struct mt76_wcid *wcid,
116- int pid, __le32 *txs_data,
117- struct mt76_sta_stats *stats);
118+ int pid, __le32 *txs_data);
119 void mt76_connac2_mac_decode_he_radiotap(struct mt76_dev *dev,
120 struct sk_buff *skb,
121 __le32 *rxv, u32 mode);
122diff --git a/mt76_connac2_mac.h b/mt76_connac2_mac.h
123index 67ce216..c7064ba 100644
124--- a/mt76_connac2_mac.h
125+++ b/mt76_connac2_mac.h
126@@ -123,6 +123,12 @@ enum {
127 /* VHT/HE only use bits 0-3 */
128 #define MT_TX_RATE_IDX GENMASK(5, 0)
129
130+enum {
131+ MT_TXS_MPDU_FM0,
132+ MT_TXS_MPDU_FM1,
133+ MT_TXS_PPDU_FM
134+};
135+
136 #define MT_TXS0_FIXED_RATE BIT(31)
137 #define MT_TXS0_BW GENMASK(30, 29)
138 #define MT_TXS0_TID GENMASK(28, 26)
139@@ -158,6 +164,14 @@ enum {
140
141 #define MT_TXS4_TIMESTAMP GENMASK(31, 0)
142
143+/* PPDU based */
144+#define MT_TXS5_MPDU_TX_BYTE GENMASK(22, 0)
145+#define MT_TXS5_MPDU_TX_CNT GENMASK(31, 23)
146+
147+#define MT_TXS6_MPDU_FAIL_CNT GENMASK(31, 23)
148+
149+#define MT_TXS7_MPDU_RETRY_CNT GENMASK(31, 23)
150+
151 /* RXD DW1 */
152 #define MT_RXD1_NORMAL_WLAN_IDX GENMASK(9, 0)
153 #define MT_RXD1_NORMAL_GROUP_1 BIT(11)
154diff --git a/mt76_connac_mac.c b/mt76_connac_mac.c
155index c1e8955..9e80cae 100644
156--- a/mt76_connac_mac.c
157+++ b/mt76_connac_mac.c
158@@ -471,6 +471,9 @@ void mt76_connac2_mac_write_txwi(struct mt76_dev *dev, __le32 *txwi,
159 p_fmt = mt76_is_mmio(dev) ? MT_TX_TYPE_CT : MT_TX_TYPE_SF;
160 q_idx = wmm_idx * MT76_CONNAC_MAX_WMM_SETS +
161 mt76_connac_lmac_mapping(skb_get_queue_mapping(skb));
162+
163+ wcid->stats.tx_bytes += skb->len;
164+ wcid->stats.tx_packets++;
165 }
166
167 val = FIELD_PREP(MT_TXD0_TX_BYTES, skb->len + sz_txd) |
168@@ -539,35 +542,26 @@ void mt76_connac2_mac_write_txwi(struct mt76_dev *dev, __le32 *txwi,
169 }
170 EXPORT_SYMBOL_GPL(mt76_connac2_mac_write_txwi);
171
172-bool mt76_connac2_mac_add_txs_skb(struct mt76_dev *dev, struct mt76_wcid *wcid,
173- int pid, __le32 *txs_data,
174- struct mt76_sta_stats *stats)
175+bool mt76_connac2_mac_fill_txs(struct mt76_dev *dev, struct mt76_wcid *wcid,
176+ __le32 *txs_data, struct mt76_sta_stats *stats)
177 {
178 struct ieee80211_supported_band *sband;
179 struct mt76_phy *mphy;
180- struct ieee80211_tx_info *info;
181- struct sk_buff_head list;
182 struct rate_info rate = {};
183- struct sk_buff *skb;
184 bool cck = false;
185 u32 txrate, txs, mode;
186
187- mt76_tx_status_lock(dev, &list);
188- skb = mt76_tx_status_skb_get(dev, wcid, pid, &list);
189- if (!skb)
190- goto out;
191-
192 txs = le32_to_cpu(txs_data[0]);
193-
194- info = IEEE80211_SKB_CB(skb);
195- if (!(txs & MT_TXS0_ACK_ERROR_MASK))
196- info->flags |= IEEE80211_TX_STAT_ACK;
197-
198- info->status.ampdu_len = 1;
199- info->status.ampdu_ack_len = !!(info->flags &
200- IEEE80211_TX_STAT_ACK);
201-
202- info->status.rates[0].idx = -1;
203+ if (FIELD_GET(MT_TXS0_TXS_FORMAT, txs) == MT_TXS_PPDU_FM) {
204+ stats->tx_bytes +=
205+ le32_get_bits(txs_data[5], MT_TXS5_MPDU_TX_BYTE);
206+ stats->tx_packets +=
207+ le32_get_bits(txs_data[5], MT_TXS5_MPDU_TX_CNT);
208+ stats->tx_failed +=
209+ le32_get_bits(txs_data[6], MT_TXS6_MPDU_FAIL_CNT);
210+ stats->tx_retries +=
211+ le32_get_bits(txs_data[7], MT_TXS7_MPDU_RETRY_CNT);
212+ }
213
214 txrate = FIELD_GET(MT_TXS0_TX_RATE, txs);
215
216@@ -602,7 +596,7 @@ bool mt76_connac2_mac_add_txs_skb(struct mt76_dev *dev, struct mt76_wcid *wcid,
217 case MT_PHY_TYPE_HT:
218 case MT_PHY_TYPE_HT_GF:
219 if (rate.mcs > 31)
220- goto out;
221+ return false;
222
223 rate.flags = RATE_INFO_FLAGS_MCS;
224 if (wcid->rate.flags & RATE_INFO_FLAGS_SHORT_GI)
225@@ -610,7 +604,7 @@ bool mt76_connac2_mac_add_txs_skb(struct mt76_dev *dev, struct mt76_wcid *wcid,
226 break;
227 case MT_PHY_TYPE_VHT:
228 if (rate.mcs > 9)
229- goto out;
230+ return false;
231
232 rate.flags = RATE_INFO_FLAGS_VHT_MCS;
233 break;
234@@ -619,14 +613,14 @@ bool mt76_connac2_mac_add_txs_skb(struct mt76_dev *dev, struct mt76_wcid *wcid,
235 case MT_PHY_TYPE_HE_TB:
236 case MT_PHY_TYPE_HE_MU:
237 if (rate.mcs > 11)
238- goto out;
239+ return false;
240
241 rate.he_gi = wcid->rate.he_gi;
242 rate.he_dcm = FIELD_GET(MT_TX_RATE_DCM, txrate);
243 rate.flags = RATE_INFO_FLAGS_HE_MCS;
244 break;
245 default:
246- goto out;
247+ return false;
248 }
249
250 stats->tx_mode[mode]++;
251@@ -651,10 +645,37 @@ bool mt76_connac2_mac_add_txs_skb(struct mt76_dev *dev, struct mt76_wcid *wcid,
252 }
253 wcid->rate = rate;
254
255-out:
256- if (skb)
257- mt76_tx_status_skb_done(dev, skb, &list);
258+ return true;
259+}
260+EXPORT_SYMBOL_GPL(mt76_connac2_mac_fill_txs);
261+
262+bool mt76_connac2_mac_add_txs_skb(struct mt76_dev *dev, struct mt76_wcid *wcid,
263+ int pid, __le32 *txs_data)
264+{
265+ struct mt76_sta_stats *stats = &wcid->stats;
266+ struct sk_buff_head list;
267+ struct sk_buff *skb;
268+
269+ if (pid < MT_PACKET_ID_FIRST)
270+ return false;
271
272+ mt76_tx_status_lock(dev, &list);
273+ skb = mt76_tx_status_skb_get(dev, wcid, pid, &list);
274+ if (skb) {
275+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
276+
277+ if (!(le32_to_cpu(txs_data[0]) & MT_TXS0_ACK_ERROR_MASK))
278+ info->flags |= IEEE80211_TX_STAT_ACK;
279+
280+ info->status.rates[0].idx = -1;
281+ info->status.ampdu_len = 1;
282+ info->status.ampdu_ack_len = !!(info->flags &
283+ IEEE80211_TX_STAT_ACK);
284+ stats->tx_failed += !(info->flags & IEEE80211_TX_STAT_ACK);
285+
286+ mt76_connac2_mac_fill_txs(dev, wcid, txs_data, stats);
287+ mt76_tx_status_skb_done(dev, skb, &list);
288+ }
289 mt76_tx_status_unlock(dev, &list);
290
291 return !!skb;
292diff --git a/mt7915/mac.c b/mt7915/mac.c
293index 1f8e123..5f42b46 100644
294--- a/mt7915/mac.c
295+++ b/mt7915/mac.c
296@@ -1152,13 +1152,10 @@ static void mt7915_mac_add_txs(struct mt7915_dev *dev, void *data)
297 u16 wcidx;
298 u8 pid;
299
300- if (le32_get_bits(txs_data[0], MT_TXS0_TXS_FORMAT) > 1)
301- return;
302-
303 wcidx = le32_get_bits(txs_data[2], MT_TXS2_WCID);
304 pid = le32_get_bits(txs_data[3], MT_TXS3_PID);
305
306- if (pid < MT_PACKET_ID_FIRST)
307+ if (pid < MT_PACKET_ID_WED)
308 return;
309
310 if (wcidx >= mt7915_wtbl_size(dev))
311@@ -1172,8 +1169,11 @@ static void mt7915_mac_add_txs(struct mt7915_dev *dev, void *data)
312
313 msta = container_of(wcid, struct mt7915_sta, wcid);
314
315- mt76_connac2_mac_add_txs_skb(&dev->mt76, wcid, pid, txs_data,
316- &msta->stats);
317+ if (pid == MT_PACKET_ID_WED)
318+ mt76_connac2_mac_fill_txs(&dev->mt76, wcid, txs_data,
319+ &msta->wcid.stats);
320+ else
321+ mt76_connac2_mac_add_txs_skb(&dev->mt76, wcid, pid, txs_data);
322 if (!wcid->sta)
323 goto out;
324
325diff --git a/mt7915/main.c b/mt7915/main.c
326index cfc522f..85d6be8 100644
327--- a/mt7915/main.c
328+++ b/mt7915/main.c
329@@ -1042,6 +1042,20 @@ static void mt7915_sta_statistics(struct ieee80211_hw *hw,
330 }
331 sinfo->txrate.flags = txrate->flags;
332 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE);
333+
334+ if (mtk_wed_device_active(&phy->dev->mt76.mmio.wed)) {
335+ sinfo->tx_bytes = msta->wcid.stats.tx_bytes;
336+ sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BYTES64);
337+
338+ sinfo->tx_packets = msta->wcid.stats.tx_packets;
339+ sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_PACKETS);
340+
341+ sinfo->tx_failed = msta->wcid.stats.tx_failed;
342+ sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_FAILED);
343+
344+ sinfo->tx_retries = msta->wcid.stats.tx_retries;
345+ sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_RETRIES);
346+ }
347 }
348
349 static void mt7915_sta_rc_work(void *data, struct ieee80211_sta *sta)
350@@ -1256,7 +1270,7 @@ static void mt7915_ethtool_worker(void *wi_data, struct ieee80211_sta *sta)
351 if (msta->vif->mt76.idx != wi->idx)
352 return;
353
354- mt76_ethtool_worker(wi, &msta->stats);
355+ mt76_ethtool_worker(wi, &msta->wcid.stats);
356 }
357
358 static
359diff --git a/mt7915/mmio.c b/mt7915/mmio.c
360index 08ff556..080bfe7 100644
361--- a/mt7915/mmio.c
362+++ b/mt7915/mmio.c
363@@ -92,6 +92,7 @@ static const u32 mt7915_offs[] = {
364 [AGG_AWSCR0] = 0x05c,
365 [AGG_PCR0] = 0x06c,
366 [AGG_ACR0] = 0x084,
367+ [AGG_ACR4] = 0x08C,
368 [AGG_MRCR] = 0x098,
369 [AGG_ATCR1] = 0x0f0,
370 [AGG_ATCR3] = 0x0f4,
371@@ -167,6 +168,7 @@ static const u32 mt7916_offs[] = {
372 [AGG_AWSCR0] = 0x030,
373 [AGG_PCR0] = 0x040,
374 [AGG_ACR0] = 0x054,
375+ [AGG_ACR4] = 0x05C,
376 [AGG_MRCR] = 0x068,
377 [AGG_ATCR1] = 0x1a8,
378 [AGG_ATCR3] = 0x080,
379@@ -668,9 +670,12 @@ irqreturn_t mt7915_irq_handler(int irq, void *dev_instance)
380 static int mt7915_wed_offload_enable(struct mtk_wed_device *wed)
381 {
382 struct mt7915_dev *dev;
383+ struct mt7915_phy *phy;
384 int ret;
385
386 dev = container_of(wed, struct mt7915_dev, mt76.mmio.wed);
387+ if (!dev)
388+ return -EINVAL;
389
390 spin_lock_bh(&dev->mt76.token_lock);
391 dev->mt76.token_size = wed->wlan.token_start;
392@@ -681,18 +686,35 @@ static int mt7915_wed_offload_enable(struct mtk_wed_device *wed)
393 if (!ret)
394 return -EAGAIN;
395
396+ phy = &dev->phy;
397+ mt76_set(dev, MT_AGG_ACR4(phy->band_idx), MT_AGG_ACR_PPDU_TXS2H);
398+
399+ phy = dev->mt76.phy2 ? dev->mt76.phy2->priv : NULL;
400+ if (phy)
401+ mt76_set(dev, MT_AGG_ACR4(phy->band_idx), MT_AGG_ACR_PPDU_TXS2H);
402+
403 return 0;
404 }
405
406 static void mt7915_wed_offload_disable(struct mtk_wed_device *wed)
407 {
408 struct mt7915_dev *dev;
409+ struct mt7915_phy *phy;
410
411 dev = container_of(wed, struct mt7915_dev, mt76.mmio.wed);
412+ if (!dev)
413+ return;
414
415 spin_lock_bh(&dev->mt76.token_lock);
416 dev->mt76.token_size = wed->wlan.token_start;//MT7915_TOKEN_SIZE;
417 spin_unlock_bh(&dev->mt76.token_lock);
418+
419+ phy = &dev->phy;
420+ mt76_clear(dev, MT_AGG_ACR4(phy->band_idx), MT_AGG_ACR_PPDU_TXS2H);
421+
422+ phy = dev->mt76.phy2 ? dev->mt76.phy2->priv : NULL;
423+ if (phy)
424+ mt76_clear(dev, MT_AGG_ACR4(phy->band_idx), MT_AGG_ACR_PPDU_TXS2H);
425 }
426 #endif
427
428diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
429index 22399cc..065c16c 100644
430--- a/mt7915/mt7915.h
431+++ b/mt7915/mt7915.h
432@@ -139,8 +139,6 @@ struct mt7915_sta {
433 unsigned long jiffies;
434 unsigned long ampdu_state;
435
436- struct mt76_sta_stats stats;
437-
438 struct mt76_connac_sta_key_conf bip;
439
440 struct {
441diff --git a/mt7915/regs.h b/mt7915/regs.h
442index 08bf84c..694cc56 100644
443--- a/mt7915/regs.h
444+++ b/mt7915/regs.h
445@@ -58,6 +58,7 @@ enum offs_rev {
446 AGG_AWSCR0,
447 AGG_PCR0,
448 AGG_ACR0,
449+ AGG_ACR4,
450 AGG_MRCR,
451 AGG_ATCR1,
452 AGG_ATCR3,
453@@ -495,6 +496,9 @@ enum offs_rev {
454 #define MT_AGG_ACR_CFEND_RATE GENMASK(13, 0)
455 #define MT_AGG_ACR_BAR_RATE GENMASK(29, 16)
456
457+#define MT_AGG_ACR4(_band) MT_WF_AGG(_band, __OFFS(AGG_ACR4))
458+#define MT_AGG_ACR_PPDU_TXS2H BIT(1)
459+
460 #define MT_AGG_MRCR(_band) MT_WF_AGG(_band, __OFFS(AGG_MRCR))
461 #define MT_AGG_MRCR_BAR_CNT_LIMIT GENMASK(15, 12)
462 #define MT_AGG_MRCR_LAST_RTS_CTS_RN BIT(6)
463diff --git a/mt7921/mt7921.h b/mt7921/mt7921.h
464index 4b2e974..f48295f 100644
465--- a/mt7921/mt7921.h
466+++ b/mt7921/mt7921.h
467@@ -100,7 +100,6 @@ struct mt7921_sta {
468
469 unsigned long last_txs;
470 unsigned long ampdu_state;
471- struct mt76_sta_stats stats;
472
473 struct mt76_connac_sta_key_conf bip;
474 };
475--
4762.32.0
477