blob: 343129f95650425fcdb6040d7e41e15b400bbbf0 [file] [log] [blame]
developer05f3b2b2024-08-19 19:17:34 +08001From 06c0ba03cc9ed39bee42b10a1e22f9aceeb57ecd Mon Sep 17 00:00:00 2001
2From: Benjamin Lin <benjamin-jw.lin@mediatek.com>
3Date: Fri, 7 Jun 2024 10:44:45 +0800
4Subject: [PATCH 153/199] mtk: mt76: mt7996: update TX/RX rates via MCU command
5
6Update TX/RX rates via MCU command to address following issues:
71. TX rate was originally updated via TXS. However in MLO connection, WCID from TXS may not represent the actually used link.
82. RX rate was originally updated via RXD. However, there is no RXD when HW path is taken.
9
10Original TX-rate update via TXS is removed.
11Still, RX-rate update via RXD is not removed, because mac80211 requires driver to provide such information for each received frame.
12
13Signed-off-by: Benjamin Lin <benjamin-jw.lin@mediatek.com>
14---
15 mt76.h | 1 +
16 mt7996/mac.c | 117 ++++++----------------------------------
17 mt7996/main.c | 28 ++++------
18 mt7996/mcu.c | 146 +++++++++++++++++++++++++++++++++++++++++++++-----
19 4 files changed, 161 insertions(+), 131 deletions(-)
20
21diff --git a/mt76.h b/mt76.h
22index f544814e..a0fc8b1a 100644
23--- a/mt76.h
24+++ b/mt76.h
25@@ -370,6 +370,7 @@ struct mt76_wcid {
26 int inactive_count;
27
28 struct rate_info rate;
29+ struct rate_info rx_rate;
30 unsigned long ampdu_state;
31
32 u16 idx;
33diff --git a/mt7996/mac.c b/mt7996/mac.c
34index 020203ec..484b679b 100644
35--- a/mt7996/mac.c
36+++ b/mt7996/mac.c
37@@ -1242,15 +1242,12 @@ mt7996_mac_add_txs_skb(struct mt7996_dev *dev, struct mt76_wcid *wcid,
38 int pid, __le32 *txs_data)
39 {
40 struct mt76_sta_stats *stats = &wcid->stats;
41- struct ieee80211_supported_band *sband;
42 struct mt76_dev *mdev = &dev->mt76;
43- struct mt76_phy *mphy;
44 struct ieee80211_tx_info *info;
45 struct sk_buff_head list;
46- struct rate_info rate = {};
47 struct sk_buff *skb = NULL;
48- bool cck = false;
49- u32 txrate, txs, mode, stbc;
50+ u32 txrate, txs;
51+ u8 mode, bw, mcs, nss;
52
53 txs = le32_to_cpu(txs_data[0]);
54
55@@ -1298,105 +1295,23 @@ mt7996_mac_add_txs_skb(struct mt7996_dev *dev, struct mt76_wcid *wcid,
56 }
57
58 txrate = FIELD_GET(MT_TXS0_TX_RATE, txs);
59-
60- rate.mcs = FIELD_GET(MT_TX_RATE_IDX, txrate);
61- rate.nss = FIELD_GET(MT_TX_RATE_NSS, txrate) + 1;
62- stbc = le32_get_bits(txs_data[3], MT_TXS3_RATE_STBC);
63-
64- if (stbc && rate.nss > 1)
65- rate.nss >>= 1;
66-
67- if (rate.nss - 1 < ARRAY_SIZE(stats->tx_nss))
68- stats->tx_nss[rate.nss - 1]++;
69- if (rate.mcs < ARRAY_SIZE(stats->tx_mcs))
70- stats->tx_mcs[rate.mcs]++;
71+ bw = FIELD_GET(MT_TXS0_BW, txs);
72
73 mode = FIELD_GET(MT_TX_RATE_MODE, txrate);
74- switch (mode) {
75- case MT_PHY_TYPE_CCK:
76- cck = true;
77- fallthrough;
78- case MT_PHY_TYPE_OFDM:
79- mphy = mt76_dev_phy(mdev, wcid->phy_idx);
80-
81- if (mphy->chandef.chan->band == NL80211_BAND_5GHZ)
82- sband = &mphy->sband_5g.sband;
83- else if (mphy->chandef.chan->band == NL80211_BAND_6GHZ)
84- sband = &mphy->sband_6g.sband;
85- else
86- sband = &mphy->sband_2g.sband;
87-
88- rate.mcs = mt76_get_rate(mphy->dev, sband, rate.mcs, cck);
89- rate.legacy = sband->bitrates[rate.mcs].bitrate;
90- break;
91- case MT_PHY_TYPE_HT:
92- case MT_PHY_TYPE_HT_GF:
93- if (rate.mcs > 31)
94- goto out;
95-
96- rate.flags = RATE_INFO_FLAGS_MCS;
97- if (wcid->rate.flags & RATE_INFO_FLAGS_SHORT_GI)
98- rate.flags |= RATE_INFO_FLAGS_SHORT_GI;
99- break;
100- case MT_PHY_TYPE_VHT:
101- if (rate.mcs > 9)
102- goto out;
103-
104- rate.flags = RATE_INFO_FLAGS_VHT_MCS;
105- if (wcid->rate.flags & RATE_INFO_FLAGS_SHORT_GI)
106- rate.flags |= RATE_INFO_FLAGS_SHORT_GI;
107- break;
108- case MT_PHY_TYPE_HE_SU:
109- case MT_PHY_TYPE_HE_EXT_SU:
110- case MT_PHY_TYPE_HE_TB:
111- case MT_PHY_TYPE_HE_MU:
112- if (rate.mcs > 11)
113- goto out;
114-
115- rate.he_gi = wcid->rate.he_gi;
116- rate.he_dcm = FIELD_GET(MT_TX_RATE_DCM, txrate);
117- rate.flags = RATE_INFO_FLAGS_HE_MCS;
118- break;
119- case MT_PHY_TYPE_EHT_SU:
120- case MT_PHY_TYPE_EHT_TRIG:
121- case MT_PHY_TYPE_EHT_MU:
122- if (rate.mcs > 13)
123- goto out;
124-
125- rate.eht_gi = wcid->rate.eht_gi;
126- rate.flags = RATE_INFO_FLAGS_EHT_MCS;
127- break;
128- default:
129- goto out;
130- }
131-
132- stats->tx_mode[mode]++;
133+ mcs = FIELD_GET(MT_TX_RATE_IDX, txrate);
134+ nss = FIELD_GET(MT_TX_RATE_NSS, txrate) + 1;
135+ if (le32_get_bits(txs_data[3], MT_TXS3_RATE_STBC) && nss > 1)
136+ nss >>= 1;
137+
138+ if (nss - 1 < ARRAY_SIZE(stats->tx_nss))
139+ stats->tx_nss[nss - 1]++;
140+ if (mcs < ARRAY_SIZE(stats->tx_mcs))
141+ stats->tx_mcs[mcs]++;
142+ if (mode < ARRAY_SIZE(stats->tx_mode))
143+ stats->tx_mode[mode]++;
144+ if (bw < ARRAY_SIZE(stats->tx_bw))
145+ stats->tx_bw[bw]++;
146
147- switch (FIELD_GET(MT_TXS0_BW, txs)) {
148- case IEEE80211_STA_RX_BW_320:
149- rate.bw = RATE_INFO_BW_320;
150- stats->tx_bw[4]++;
151- break;
152- case IEEE80211_STA_RX_BW_160:
153- rate.bw = RATE_INFO_BW_160;
154- stats->tx_bw[3]++;
155- break;
156- case IEEE80211_STA_RX_BW_80:
157- rate.bw = RATE_INFO_BW_80;
158- stats->tx_bw[2]++;
159- break;
160- case IEEE80211_STA_RX_BW_40:
161- rate.bw = RATE_INFO_BW_40;
162- stats->tx_bw[1]++;
163- break;
164- default:
165- rate.bw = RATE_INFO_BW_20;
166- stats->tx_bw[0]++;
167- break;
168- }
169- wcid->rate = rate;
170-
171-out:
172 if (skb)
173 mt76_tx_status_skb_done(mdev, skb, &list);
174 mt76_tx_status_unlock(mdev, &list);
175diff --git a/mt7996/main.c b/mt7996/main.c
176index 19a1c7b3..fa60b889 100644
177--- a/mt7996/main.c
178+++ b/mt7996/main.c
179@@ -1765,32 +1765,24 @@ static void mt7996_sta_statistics(struct ieee80211_hw *hw,
180 struct mt7996_phy *phy = mt7996_hw_phy(hw);
181 struct mt7996_sta *msta = (struct mt7996_sta *)sta->drv_priv;
182 struct mt7996_link_sta *mlink;
183- struct rate_info *txrate;
184+ struct rate_info *rate;
185
186- /* TODO: support per-link rate report */
187 mutex_lock(&dev->mt76.mutex);
188 mlink = mlink_dereference_protected(msta, msta->pri_link);
189 if (!mlink)
190 goto out;
191
192- txrate = &mlink->wcid.rate;
193- if (txrate->legacy || txrate->flags) {
194- if (txrate->legacy) {
195- sinfo->txrate.legacy = txrate->legacy;
196- } else {
197- sinfo->txrate.mcs = txrate->mcs;
198- sinfo->txrate.nss = txrate->nss;
199- sinfo->txrate.bw = txrate->bw;
200- sinfo->txrate.he_gi = txrate->he_gi;
201- sinfo->txrate.he_dcm = txrate->he_dcm;
202- sinfo->txrate.he_ru_alloc = txrate->he_ru_alloc;
203- sinfo->txrate.eht_gi = txrate->eht_gi;
204- }
205- sinfo->txrate.flags = txrate->flags;
206+ rate = &mlink->wcid.rate;
207+ if (rate->legacy || rate->flags) {
208+ sinfo->txrate = *rate;
209 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE);
210 }
211- sinfo->txrate.flags = txrate->flags;
212- sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE);
213+
214+ rate = &mlink->wcid.rx_rate;
215+ if (rate->legacy || rate->flags) {
216+ sinfo->rxrate = *rate;
217+ sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_BITRATE);
218+ }
219
220 sinfo->tx_failed = mlink->wcid.stats.tx_failed;
221 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_FAILED);
222diff --git a/mt7996/mcu.c b/mt7996/mcu.c
223index 51f15928..8fd9d450 100644
224--- a/mt7996/mcu.c
225+++ b/mt7996/mcu.c
226@@ -532,42 +532,164 @@ mt7996_mcu_ie_countdown(struct mt7996_dev *dev, struct sk_buff *skb)
227 }
228
229 static int
230-mt7996_mcu_update_tx_gi(struct rate_info *rate, struct all_sta_trx_rate *mcu_rate)
231+mt7996_mcu_update_rate(struct rate_info *rate, struct ieee80211_supported_band *sband,
232+ u8 mode, u8 bw, u8 mcs, u8 nss, u8 stbc, u8 gi)
233 {
234- switch (mcu_rate->tx_mode) {
235+ struct rate_info tmp_rate = {};
236+
237+ tmp_rate.mcs = mcs;
238+ tmp_rate.nss = (stbc && nss > 1) ? nss / 2 : nss;
239+
240+ switch (mode) {
241 case MT_PHY_TYPE_CCK:
242 case MT_PHY_TYPE_OFDM:
243+ if (mcs >= sband->n_bitrates)
244+ return -EINVAL;
245+
246+ tmp_rate.legacy = sband->bitrates[mcs].bitrate;
247 break;
248 case MT_PHY_TYPE_HT:
249 case MT_PHY_TYPE_HT_GF:
250+ if (mcs > 31)
251+ return -EINVAL;
252+
253+ tmp_rate.flags |= RATE_INFO_FLAGS_MCS;
254+ if (gi)
255+ tmp_rate.flags |= RATE_INFO_FLAGS_SHORT_GI;
256+ break;
257 case MT_PHY_TYPE_VHT:
258- if (mcu_rate->tx_gi)
259- rate->flags |= RATE_INFO_FLAGS_SHORT_GI;
260- else
261- rate->flags &= ~RATE_INFO_FLAGS_SHORT_GI;
262+ if (mcs > 9)
263+ return -EINVAL;
264+
265+ tmp_rate.flags |= RATE_INFO_FLAGS_VHT_MCS;
266+ if (gi)
267+ tmp_rate.flags |= RATE_INFO_FLAGS_SHORT_GI;
268 break;
269 case MT_PHY_TYPE_HE_SU:
270 case MT_PHY_TYPE_HE_EXT_SU:
271 case MT_PHY_TYPE_HE_TB:
272 case MT_PHY_TYPE_HE_MU:
273- if (mcu_rate->tx_gi > NL80211_RATE_INFO_HE_GI_3_2)
274+ tmp_rate.mcs = mcs & GENMASK(3, 0);
275+ if (tmp_rate.mcs > 11 || gi > NL80211_RATE_INFO_HE_GI_3_2)
276 return -EINVAL;
277- rate->he_gi = mcu_rate->tx_gi;
278+
279+ tmp_rate.flags |= RATE_INFO_FLAGS_HE_MCS;
280+ tmp_rate.he_gi = gi;
281+ tmp_rate.he_dcm = mcs & MT_PRXV_TX_DCM;
282 break;
283 case MT_PHY_TYPE_EHT_SU:
284 case MT_PHY_TYPE_EHT_TRIG:
285 case MT_PHY_TYPE_EHT_MU:
286- if (mcu_rate->tx_gi > NL80211_RATE_INFO_EHT_GI_3_2)
287+ tmp_rate.mcs = mcs & GENMASK(3, 0);
288+ if (tmp_rate.mcs > 13 || gi > NL80211_RATE_INFO_EHT_GI_3_2)
289 return -EINVAL;
290- rate->eht_gi = mcu_rate->tx_gi;
291+
292+ tmp_rate.flags |= RATE_INFO_FLAGS_EHT_MCS;
293+ tmp_rate.eht_gi = gi;
294 break;
295 default:
296 return -EINVAL;
297 }
298
299+ switch (bw) {
300+ case IEEE80211_STA_RX_BW_20:
301+ tmp_rate.bw = RATE_INFO_BW_20;
302+ break;
303+ case IEEE80211_STA_RX_BW_40:
304+ tmp_rate.bw = RATE_INFO_BW_40;
305+ break;
306+ case IEEE80211_STA_RX_BW_80:
307+ tmp_rate.bw = RATE_INFO_BW_80;
308+ break;
309+ case IEEE80211_STA_RX_BW_160:
310+ tmp_rate.bw = RATE_INFO_BW_160;
311+ break;
312+ case IEEE80211_STA_RX_BW_320:
313+ tmp_rate.bw = RATE_INFO_BW_320;
314+ break;
315+ default:
316+ return -EINVAL;
317+ }
318+
319+ if (mode == MT_PHY_TYPE_HE_EXT_SU && mcs & MT_PRXV_TX_ER_SU_106T) {
320+ tmp_rate.bw = RATE_INFO_BW_HE_RU;
321+ tmp_rate.he_ru_alloc = NL80211_RATE_INFO_HE_RU_ALLOC_106;
322+ }
323+ *rate = tmp_rate;
324+
325 return 0;
326 }
327
328+static int
329+mt7996_mcu_update_trx_rates(struct mt76_wcid *wcid, struct all_sta_trx_rate *mcu_rate)
330+{
331+ struct mt7996_link_sta *mlink = container_of(wcid, struct mt7996_link_sta, wcid);
332+ struct mt76_dev *dev = &mlink->sta->vif->dev->mt76;
333+ struct mt76_phy *phy = mt76_dev_phy(dev, wcid->phy_idx);
334+ struct ieee80211_supported_band *sband = NULL;
335+ bool cck;
336+ int ret;
337+
338+ /* TX rate */
339+ cck = false;
340+
341+ switch (mcu_rate->tx_mode) {
342+ case MT_PHY_TYPE_CCK:
343+ cck = true;
344+ fallthrough;
345+ case MT_PHY_TYPE_OFDM:
346+ if (phy->chandef.chan->band == NL80211_BAND_2GHZ) {
347+ sband = &phy->sband_2g.sband;
348+ if (!cck)
349+ mcu_rate->tx_mcs += 4;
350+ } else if (phy->chandef.chan->band == NL80211_BAND_5GHZ)
351+ sband = &phy->sband_5g.sband;
352+ else
353+ sband = &phy->sband_6g.sband;
354+ break;
355+ case MT_PHY_TYPE_HT:
356+ case MT_PHY_TYPE_HT_GF:
357+ mcu_rate->tx_mcs += ((mcu_rate->tx_nss - 1) << 3);
358+ break;
359+ default:
360+ break;
361+ }
362+
363+ ret = mt7996_mcu_update_rate(&wcid->rate, sband, mcu_rate->tx_mode,
364+ mcu_rate->tx_bw, mcu_rate->tx_mcs,
365+ mcu_rate->tx_nss, mcu_rate->tx_stbc,
366+ mcu_rate->tx_gi);
367+ if (ret)
368+ return ret;
369+
370+ /* RX rate */
371+ cck = false;
372+
373+ switch (mcu_rate->rx_mode) {
374+ case MT_PHY_TYPE_CCK:
375+ cck = true;
376+ fallthrough;
377+ case MT_PHY_TYPE_OFDM:
378+ if (phy->chandef.chan->band == NL80211_BAND_2GHZ)
379+ sband = &phy->sband_2g.sband;
380+ else if (phy->chandef.chan->band == NL80211_BAND_5GHZ)
381+ sband = &phy->sband_5g.sband;
382+ else
383+ sband = &phy->sband_6g.sband;
384+
385+ mcu_rate->rx_rate = mt76_get_rate(dev, sband, mcu_rate->rx_rate, cck);
386+ break;
387+ default:
388+ break;
389+ }
390+
391+ ret = mt7996_mcu_update_rate(&wcid->rx_rate, sband, mcu_rate->rx_mode,
392+ mcu_rate->rx_bw, mcu_rate->rx_rate,
393+ mcu_rate->rx_nsts + 1, mcu_rate->rx_stbc,
394+ mcu_rate->rx_gi);
395+ return ret;
396+}
397+
398 static inline void __mt7996_stat_to_netdev(struct mt76_phy *mphy,
399 struct mt76_wcid *wcid,
400 u32 tx_bytes, u32 rx_bytes,
401@@ -618,8 +740,8 @@ mt7996_mcu_rx_all_sta_info_event(struct mt7996_dev *dev, struct sk_buff *skb)
402 if (!wcid)
403 break;
404
405- if (mt7996_mcu_update_tx_gi(&wcid->rate, &res->rate[i]))
406- dev_err(dev->mt76.dev, "Failed to update TX GI\n");
407+ if (mt7996_mcu_update_trx_rates(wcid, &res->rate[i]))
408+ dev_err(dev->mt76.dev, "Failed to update TX/RX rates.\n");
409 break;
410 case UNI_ALL_STA_TXRX_ADM_STAT:
411 wlan_idx = le16_to_cpu(res->adm_stat[i].wlan_idx);
412--
4132.18.0
414