blob: 3a0e69c22683a2cb8824b1d27af037d022311084 [file] [log] [blame]
developer1d9da7d2023-04-15 12:45:34 +08001From 4edd13ceb916e12acbd91011268e192b867fd747 Mon Sep 17 00:00:00 2001
developer1557f6c2023-04-13 18:48:23 +08002From: Benjamin Lin <benjamin-jw.lin@mediatek.com>
3Date: Fri, 24 Mar 2023 18:01:27 +0800
4Subject: [PATCH 5/5] wifi: mt76: fix incorrect HE TX GI report
5
6Change GI reporting source from static capability to rate-tuning module.
7
8Signed-off-by: Benjamin Lin <benjamin-jw.lin@mediatek.com>
9---
10 mt76.h | 4 ++
11 mt7915/init.c | 4 ++
12 mt7915/mac.c | 54 ++++++++++++++---------
13 mt7915/main.c | 7 +++
14 mt7915/mcu.c | 114 ++++++++++++++++++++++++++++++++++++++++++++++++
15 mt7915/mcu.h | 39 +++++++++++++++++
16 mt7915/mt7915.h | 6 +++
17 7 files changed, 208 insertions(+), 20 deletions(-)
18
19diff --git a/mt76.h b/mt76.h
developer1d9da7d2023-04-15 12:45:34 +080020index 183b0fc..11d4936 100644
developer1557f6c2023-04-13 18:48:23 +080021--- a/mt76.h
22+++ b/mt76.h
23@@ -254,12 +254,16 @@ struct mt76_queue_ops {
24 void (*reset_q)(struct mt76_dev *dev, struct mt76_queue *q);
25 };
26
27+#define MT_PHY_TYPE_LEGACY GENMASK(2, 0)
28+#define MT_PHY_TYPE_EXT GENMASK(7, 3)
29+
30 enum mt76_phy_type {
31 MT_PHY_TYPE_CCK,
32 MT_PHY_TYPE_OFDM,
33 MT_PHY_TYPE_HT,
34 MT_PHY_TYPE_HT_GF,
35 MT_PHY_TYPE_VHT,
36+ MT_PHY_TYPE_HE_REMAP,
37 MT_PHY_TYPE_HE_SU = 8,
38 MT_PHY_TYPE_HE_EXT_SU,
39 MT_PHY_TYPE_HE_TB,
40diff --git a/mt7915/init.c b/mt7915/init.c
developer1d9da7d2023-04-15 12:45:34 +080041index b88c382..611a82b 100644
developer1557f6c2023-04-13 18:48:23 +080042--- a/mt7915/init.c
43+++ b/mt7915/init.c
44@@ -644,6 +644,8 @@ mt7915_register_ext_phy(struct mt7915_dev *dev, struct mt7915_phy *phy)
45 struct mt76_phy *mphy = phy->mt76;
46 int ret;
47
48+ INIT_LIST_HEAD(&phy->stats_list);
49+ spin_lock_init(&phy->stats_lock);
50 INIT_DELAYED_WORK(&mphy->mac_work, mt7915_mac_work);
51
52 mt7915_eeprom_parse_hw_cap(dev, phy);
53@@ -1197,6 +1199,8 @@ int mt7915_register_device(struct mt7915_dev *dev)
54 dev->phy.dev = dev;
55 dev->phy.mt76 = &dev->mt76.phy;
56 dev->mt76.phy.priv = &dev->phy;
57+ INIT_LIST_HEAD(&dev->phy.stats_list);
58+ spin_lock_init(&dev->phy.stats_lock);
59 INIT_WORK(&dev->rc_work, mt7915_mac_sta_rc_work);
60 INIT_DELAYED_WORK(&dev->mphy.mac_work, mt7915_mac_work);
61 INIT_LIST_HEAD(&dev->sta_rc_list);
62diff --git a/mt7915/mac.c b/mt7915/mac.c
developer1d9da7d2023-04-15 12:45:34 +080063index f1fdcfd..d052036 100644
developer1557f6c2023-04-13 18:48:23 +080064--- a/mt7915/mac.c
65+++ b/mt7915/mac.c
66@@ -177,15 +177,7 @@ static void mt7915_mac_sta_poll(struct mt7915_dev *dev)
67 rx_cur);
68 }
69
70- /*
71- * We don't support reading GI info from txs packets.
72- * For accurate tx status reporting and AQL improvement,
73- * we need to make sure that flags match so polling GI
74- * from per-sta counters directly.
75- */
76 rate = &msta->wcid.rate;
77- addr = mt7915_mac_wtbl_lmac_addr(dev, idx, 7);
78- val = mt76_rr(dev, addr);
79
80 switch (rate->bw) {
81 case RATE_INFO_BW_160:
82@@ -202,18 +194,6 @@ static void mt7915_mac_sta_poll(struct mt7915_dev *dev)
83 break;
84 }
85
86- if (rate->flags & RATE_INFO_FLAGS_HE_MCS) {
87- u8 offs = 24 + 2 * bw;
88-
89- rate->he_gi = (val & (0x3 << offs)) >> offs;
90- } else if (rate->flags &
91- (RATE_INFO_FLAGS_VHT_MCS | RATE_INFO_FLAGS_MCS)) {
92- if (val & BIT(12 + bw))
93- rate->flags |= RATE_INFO_FLAGS_SHORT_GI;
94- else
95- rate->flags &= ~RATE_INFO_FLAGS_SHORT_GI;
96- }
97-
98 /* get signal strength of resp frames (CTS/BA/ACK) */
99 addr = mt7915_mac_wtbl_lmac_addr(dev, idx, 30);
100 val = mt76_rr(dev, addr);
101@@ -982,6 +962,7 @@ mt7915_mac_tx_free(struct mt7915_dev *dev, void *data, int len)
102 if (info & MT_TX_FREE_PAIR) {
103 struct mt7915_sta *msta;
104 struct mt76_wcid *wcid;
105+ struct mt7915_phy *phy;
106 u16 idx;
107
108 idx = FIELD_GET(MT_TX_FREE_WLAN_ID, info);
109@@ -991,10 +972,17 @@ mt7915_mac_tx_free(struct mt7915_dev *dev, void *data, int len)
110 continue;
111
112 msta = container_of(wcid, struct mt7915_sta, wcid);
113+ phy = msta->vif->phy;
114 spin_lock_bh(&dev->sta_poll_lock);
115 if (list_empty(&msta->poll_list))
116 list_add_tail(&msta->poll_list, &dev->sta_poll_list);
117 spin_unlock_bh(&dev->sta_poll_lock);
118+
119+ spin_lock_bh(&phy->stats_lock);
120+ if (list_empty(&msta->stats_list))
121+ list_add_tail(&msta->stats_list, &phy->stats_list);
122+ spin_unlock_bh(&phy->stats_lock);
123+
124 continue;
125 }
126
127@@ -2016,6 +2004,27 @@ static void mt7915_mac_severe_check(struct mt7915_phy *phy)
128 phy->trb_ts = trb;
129 }
130
131+static void mt7915_mac_sta_stats_work(struct mt7915_phy *phy)
132+{
133+ struct mt7915_sta *sta;
134+ LIST_HEAD(list);
135+
136+ spin_lock_bh(&phy->stats_lock);
137+ list_splice_init(&phy->stats_list, &list);
138+
139+ while (!list_empty(&list)) {
140+ sta = list_first_entry(&list, struct mt7915_sta, stats_list);
141+ list_del_init(&sta->stats_list);
142+ spin_unlock_bh(&phy->stats_lock);
143+
144+ mt7915_mcu_get_tx_rate(phy, sta->wcid.idx);
145+
146+ spin_lock_bh(&phy->stats_lock);
147+ }
148+
149+ spin_unlock_bh(&phy->stats_lock);
150+}
151+
152 void mt7915_mac_sta_rc_work(struct work_struct *work)
153 {
154 struct mt7915_dev *dev = container_of(work, struct mt7915_dev, rc_work);
155@@ -2071,6 +2080,11 @@ void mt7915_mac_work(struct work_struct *work)
156 mt7915_mac_severe_check(phy);
157 }
158
159+ if (++phy->stats_work_count == 10) {
160+ phy->stats_work_count = 0;
161+ mt7915_mac_sta_stats_work(phy);
162+ }
163+
164 mutex_unlock(&mphy->dev->mutex);
165
166 mt76_tx_status_check(mphy->dev, false);
167diff --git a/mt7915/main.c b/mt7915/main.c
developer1d9da7d2023-04-15 12:45:34 +0800168index ea1d4e6..870b7b2 100644
developer1557f6c2023-04-13 18:48:23 +0800169--- a/mt7915/main.c
170+++ b/mt7915/main.c
171@@ -684,6 +684,7 @@ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
172
173 INIT_LIST_HEAD(&msta->rc_list);
174 INIT_LIST_HEAD(&msta->poll_list);
175+ INIT_LIST_HEAD(&msta->stats_list);
176 msta->vif = mvif;
177 msta->wcid.sta = 1;
178 msta->wcid.idx = idx;
179@@ -708,6 +709,7 @@ void mt7915_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif,
180 {
181 struct mt7915_dev *dev = container_of(mdev, struct mt7915_dev, mt76);
182 struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv;
183+ struct mt7915_phy *phy = msta->vif->phy;
184 int i;
185
186 mt7915_mcu_add_sta(dev, vif, sta, false);
187@@ -724,6 +726,11 @@ void mt7915_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif,
188 if (!list_empty(&msta->rc_list))
189 list_del_init(&msta->rc_list);
190 spin_unlock_bh(&dev->sta_poll_lock);
191+
192+ spin_lock_bh(&phy->stats_lock);
193+ if (!list_empty(&msta->stats_list))
194+ list_del_init(&msta->stats_list);
195+ spin_unlock_bh(&phy->stats_lock);
196 }
197
198 static void mt7915_tx(struct ieee80211_hw *hw,
199diff --git a/mt7915/mcu.c b/mt7915/mcu.c
developer1d9da7d2023-04-15 12:45:34 +0800200index 2a5ad03..a9f8a88 100644
developer1557f6c2023-04-13 18:48:23 +0800201--- a/mt7915/mcu.c
202+++ b/mt7915/mcu.c
203@@ -3752,6 +3752,120 @@ out:
204 return ret;
205 }
206
207+static int
208+mt7915_mcu_parse_tx_gi(struct mt7915_mcu_ra_info *mcu_rate,
209+ struct rate_info *rate)
210+{
211+ u8 mode = mcu_rate->mode;
212+ u8 gi = mcu_rate->gi;
213+
214+ /* Legacy drivers only use 3 bits for PHY mode. For backward
215+ * compatibility, HE and newer PHY mode indices are remapped
216+ * to the extended bits.
217+ */
218+ if (u8_get_bits(mode, MT_PHY_TYPE_LEGACY) == MT_PHY_TYPE_HE_REMAP)
219+ mode = u8_get_bits(mode, MT_PHY_TYPE_EXT);
220+
221+ switch (mode) {
222+ case MT_PHY_TYPE_CCK:
223+ case MT_PHY_TYPE_OFDM:
224+ break;
225+ case MT_PHY_TYPE_HT:
226+ case MT_PHY_TYPE_HT_GF:
227+ case MT_PHY_TYPE_VHT:
228+ if (gi)
229+ rate->flags |= RATE_INFO_FLAGS_SHORT_GI;
230+ break;
231+ case MT_PHY_TYPE_HE_SU:
232+ case MT_PHY_TYPE_HE_EXT_SU:
233+ case MT_PHY_TYPE_HE_TB:
234+ case MT_PHY_TYPE_HE_MU:
235+ switch (mcu_rate->bw) {
236+ case MCU_PHY_BW_20:
237+ gi = u8_get_bits(gi, HE_GI_BW_20);
238+ break;
239+ case MCU_PHY_BW_40:
240+ gi = u8_get_bits(gi, HE_GI_BW_40);
241+ break;
242+ case MCU_PHY_BW_80:
243+ gi = u8_get_bits(gi, HE_GI_BW_80);
244+ break;
245+ case MCU_PHY_BW_160:
246+ gi = u8_get_bits(gi, HE_GI_BW_160);
247+ break;
248+ default:
249+ return -EINVAL;
250+ }
251+
252+ if (gi > NL80211_RATE_INFO_HE_GI_3_2)
253+ return -EINVAL;
254+
255+ rate->he_gi = gi;
256+ break;
257+ default:
258+ return -EINVAL;
259+ }
260+
261+ return 0;
262+}
263+
264+int mt7915_mcu_get_tx_rate(struct mt7915_phy *phy, u16 wcidx)
265+{
266+ struct ieee80211_tx_status status = {};
267+ struct mt7915_dev *dev = phy->dev;
268+ struct mt76_phy *mphy = phy->mt76;
269+ struct mt7915_mcu_ra_info *rate;
270+ struct mt76_wcid *wcid;
271+ struct sk_buff *skb;
272+ int ret;
273+
274+ struct {
275+ u8 category;
276+ u8 band;
277+ __le16 wcidx;
278+ } req = {
279+ .category = MCU_GET_TX_RATE,
280+ .band = mphy->band_idx,
281+ .wcidx = cpu_to_le16(wcidx)
282+ };
283+
284+ ret = mt76_mcu_send_and_get_msg(&dev->mt76, MCU_EXT_QUERY(GET_TX_STAT),
285+ &req, sizeof(req), true, &skb);
286+ if (ret)
287+ return ret;
288+
289+ rate = (struct mt7915_mcu_ra_info *)skb->data;
290+ if (le16_to_cpu(rate->wcidx) != wcidx) {
291+ ret = -EINVAL;
292+ goto out;
293+ }
294+
295+ rcu_read_lock();
296+ wcid = rcu_dereference(dev->mt76.wcid[wcidx]);
297+ if (!wcid) {
298+ ret = -EINVAL;
299+ goto unlock;
300+ }
301+
302+ ret = mt7915_mcu_parse_tx_gi(rate, &wcid->rate);
303+ if (ret)
304+ goto unlock;
305+
306+ status.sta = wcid_to_sta(wcid);
307+ if (!status.sta) {
308+ ret = -EINVAL;
309+ goto unlock;
310+ }
311+ status.rate = &wcid->rate;
312+ ieee80211_tx_status_ext(mphy->hw, &status);
313+unlock:
314+ rcu_read_unlock();
315+out:
316+ dev_kfree_skb(skb);
317+
318+ return ret;
319+}
320+
321 int mt7915_mcu_update_bss_color(struct mt7915_dev *dev, struct ieee80211_vif *vif,
322 struct cfg80211_he_bss_color *he_bss_color)
323 {
324diff --git a/mt7915/mcu.h b/mt7915/mcu.h
developer1d9da7d2023-04-15 12:45:34 +0800325index 1592b5d..3429e24 100644
developer1557f6c2023-04-13 18:48:23 +0800326--- a/mt7915/mcu.h
327+++ b/mt7915/mcu.h
328@@ -152,6 +152,42 @@ struct mt7915_mcu_eeprom_info {
329 u8 data[16];
330 } __packed;
331
332+enum {
333+ MCU_PHY_BW_20 = 0,
334+ MCU_PHY_BW_40,
335+ MCU_PHY_BW_80,
336+ MCU_PHY_BW_160,
337+ MCU_PHY_BW_10,
338+ MCU_PHY_BW_5,
339+ MCU_PHY_BW_8080,
340+ MCU_PHY_BW_320,
341+ MCU_PHY_BW_NUM
342+};
343+
344+#define HE_GI_BW_20 GENMASK(1, 0)
345+#define HE_GI_BW_40 GENMASK(3, 2)
346+#define HE_GI_BW_80 GENMASK(5, 4)
347+#define HE_GI_BW_160 GENMASK(7, 6)
348+
349+struct mt7915_mcu_ra_info {
350+ u8 category;
351+ u8 rsv1;
352+ __le16 num;
353+ __le16 wcidx;
354+
355+ u8 mode;
356+ u8 flags;
357+ u8 stbc;
358+ u8 gi;
359+ u8 bw;
360+ u8 ldpc;
361+ u8 mcs;
362+ u8 nss;
363+ u8 ltf;
364+
365+ u8 rsv2;
366+};
367+
368 struct mt7915_mcu_phy_rx_info {
369 u8 category;
370 u8 rate;
371@@ -527,4 +563,7 @@ mt7915_get_power_bound(struct mt7915_phy *phy, s8 txpower)
372 return txpower;
373 }
374
375+enum {
376+ MCU_GET_TX_RATE = 4
377+};
378 #endif
379diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
developer1d9da7d2023-04-15 12:45:34 +0800380index 376256d..81246f3 100644
developer1557f6c2023-04-13 18:48:23 +0800381--- a/mt7915/mt7915.h
382+++ b/mt7915/mt7915.h
383@@ -131,6 +131,7 @@ struct mt7915_sta {
384
385 struct list_head poll_list;
386 struct list_head rc_list;
387+ struct list_head stats_list;
388 u32 airtime_ac[8];
389
390 int ack_signal;
391@@ -280,6 +281,10 @@ struct mt7915_phy {
392 struct mib_stats mib;
393 struct mt76_channel_state state_ts;
394
395+ u8 stats_work_count;
396+ struct list_head stats_list;
397+ spinlock_t stats_lock;
398+
399 #ifdef CONFIG_NL80211_TESTMODE
400 struct {
401 u32 *reg_backup;
402@@ -553,6 +558,7 @@ int mt7915_mcu_get_chan_mib_info(struct mt7915_phy *phy, bool chan_switch);
403 int mt7915_mcu_get_temperature(struct mt7915_phy *phy);
404 int mt7915_mcu_set_thermal_throttling(struct mt7915_phy *phy, u8 state);
405 int mt7915_mcu_set_thermal_protect(struct mt7915_phy *phy);
406+int mt7915_mcu_get_tx_rate(struct mt7915_phy *phy, u16 wcidx);
407 int mt7915_mcu_get_rx_rate(struct mt7915_phy *phy, struct ieee80211_vif *vif,
408 struct ieee80211_sta *sta, struct rate_info *rate);
409 int mt7915_mcu_rdd_background_enable(struct mt7915_phy *phy,
410--
4112.18.0
412