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