blob: ea0d36ef4c2e5d236abf44beef0112043bd7ef33 [file] [log] [blame]
developer05f3b2b2024-08-19 19:17:34 +08001From af0b14e475466b4f353c20af228c381c695ec3f9 Mon Sep 17 00:00:00 2001
developer66e89bc2024-04-23 14:50:01 +08002From: Peter Chiu <chui-hao.chiu@mediatek.com>
3Date: Mon, 1 Apr 2024 17:00:21 +0800
developer05f3b2b2024-08-19 19:17:34 +08004Subject: [PATCH 116/199] mtk: mt76: mt7996: enable ampdu limit to avoid BA
5 bound issue
developer66e89bc2024-04-23 14:50:01 +08006
7[Description]
8When the station is MTK device and the peak is higher than 15G, the PPS
9would exceed HW-RRO's bandwidth and lead to Rx fifo full and PER. When
10a link occurs PER, it may occupy SSN and the other two bands are not
11able to transmit.
12
13Limit AMPDU to 512 when satisify all of the following conditions
141. BA winsize is 1024.
152. At least one link use BW320 and its spatial stream is larger
16than 3.
173. At least one link use BW160 and its spatial stream is larger
18than 3.
19
20By limiting AMPDU to 512, it can solve this issue.
211. Reduce PPS so we can avoid Rx fifo full due to HW-RRO.
222. If a bind occupy SSN, the other two bands can use the SSN
23between 512 to 1024.
24
25[Release-log]
26N/A
27
developer66e89bc2024-04-23 14:50:01 +080028Signed-off-by: Peter Chiu <chui-hao.chiu@mediatek.com>
developer66e89bc2024-04-23 14:50:01 +080029---
30 mt76_connac_mcu.h | 1 +
31 mt7996/mcu.c | 86 +++++++++++++++++++++++++++++++++++++++++++++++
32 mt7996/mcu.h | 8 +++++
33 3 files changed, 95 insertions(+)
34
35diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
developer05f3b2b2024-08-19 19:17:34 +080036index f6a0d328..6e3324f5 100644
developer66e89bc2024-04-23 14:50:01 +080037--- a/mt76_connac_mcu.h
38+++ b/mt76_connac_mcu.h
developer05f3b2b2024-08-19 19:17:34 +080039@@ -829,6 +829,7 @@ enum {
developer66e89bc2024-04-23 14:50:01 +080040 STA_REC_KEY_V3 = 0x27,
41 STA_REC_HDRT = 0x28,
42 STA_REC_HDR_TRANS = 0x2B,
43+ STA_REC_TX_CAP = 0x2f,
44 STA_REC_MAX_NUM
45 };
46
47diff --git a/mt7996/mcu.c b/mt7996/mcu.c
developer05f3b2b2024-08-19 19:17:34 +080048index 340b6637..f97acfb2 100644
developer66e89bc2024-04-23 14:50:01 +080049--- a/mt7996/mcu.c
50+++ b/mt7996/mcu.c
51@@ -1344,6 +1344,85 @@ mt7996_mcu_sta_ba(struct mt7996_dev *dev, struct mt76_vif *mvif,
52 MCU_WMWA_UNI_CMD(STA_REC_UPDATE), true);
53 }
54
55+static int
56+mt7996_mcu_sta_tx_cap(struct mt7996_dev *dev, struct mt76_vif *mvif,
57+ struct mt76_wcid *wcid)
58+{
59+ struct sta_rec_tx_cap *tx_cap;
60+ struct sk_buff *skb;
61+ struct tlv *tlv;
62+
63+ skb = __mt76_connac_mcu_alloc_sta_req(&dev->mt76, mvif, wcid,
64+ MT7996_STA_UPDATE_MAX_SIZE);
65+ if (IS_ERR(skb))
66+ return PTR_ERR(skb);
67+
68+ tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_TX_CAP, sizeof(*tx_cap));
69+
70+ tx_cap = (struct sta_rec_tx_cap *)tlv;
71+ tx_cap->ampdu_limit_en = true;
72+
73+ dev_info(dev->mt76.dev, "%s: limit wcid %d ampdu to 512\n", __func__, wcid->idx);
74+
75+ return mt76_mcu_skb_send_msg(&dev->mt76, skb,
76+ MCU_WMWA_UNI_CMD(STA_REC_UPDATE), true);
77+}
78+
79+static bool mt7996_check_limit_ampdu_en(struct ieee80211_ampdu_params *params) {
80+ struct ieee80211_sta *sta = params->sta;
81+ struct mt7996_sta *msta = (struct mt7996_sta *)sta->drv_priv;
82+ unsigned long valid_links = sta->valid_links ?: BIT(0);
83+ unsigned int link_id;
84+ bool BW320 = false, BW160 = false;
85+
86+ if (params->buf_size < 1024)
87+ return false;
88+
89+ for_each_set_bit(link_id, &valid_links, IEEE80211_MLD_MAX_NUM_LINKS) {
90+ struct ieee80211_link_sta __rcu *link =
91+ link_sta_dereference_protected(sta, link_id);
92+ struct mt7996_bss_conf *mconf =
93+ mconf_dereference_protected(msta->vif, link_id);
94+ struct mt76_phy *phy = mconf->phy->mt76;
95+ struct ieee80211_eht_mcs_nss_supp_bw *ss = NULL;
96+ u8 sta_bw, ap_nss, sta_nss;
97+
98+ switch (phy->chandef.width) {
99+ case NL80211_CHAN_WIDTH_160:
100+ if (link->bandwidth >= IEEE80211_STA_RX_BW_160) {
101+ ss = &link->eht_cap.eht_mcs_nss_supp.bw._160;
102+ sta_bw = NL80211_CHAN_WIDTH_160;
103+ }
104+ break;
105+ case NL80211_CHAN_WIDTH_320:
106+ if (link->bandwidth == IEEE80211_STA_RX_BW_320) {
107+ ss = &link->eht_cap.eht_mcs_nss_supp.bw._320;
108+ sta_bw = NL80211_CHAN_WIDTH_320;
109+ }
110+ break;
111+ default:
112+ break;
113+ }
114+
115+ if (!ss)
116+ continue;
117+
118+ ap_nss = hweight8(phy->antenna_mask);
119+ sta_nss = max(u8_get_bits(ss->rx_tx_mcs11_max_nss, IEEE80211_EHT_MCS_NSS_RX),
120+ u8_get_bits(ss->rx_tx_mcs13_max_nss, IEEE80211_EHT_MCS_NSS_RX));
121+
122+ if (min(ap_nss, sta_nss) <= 2)
123+ continue;
124+
125+ if (sta_bw == NL80211_CHAN_WIDTH_160)
126+ BW160 = true;
127+ else if (sta_bw == NL80211_CHAN_WIDTH_320)
128+ BW320 = true;
129+ }
130+
131+ return BW320 && BW160;
132+}
133+
134 /** starec & wtbl **/
135 int mt7996_mcu_add_tx_ba(struct mt7996_dev *dev,
136 struct ieee80211_ampdu_params *params,
137@@ -1353,6 +1432,7 @@ int mt7996_mcu_add_tx_ba(struct mt7996_dev *dev,
138 struct mt7996_sta *msta = (struct mt7996_sta *)sta->drv_priv;
139 unsigned long valid_links = sta->valid_links ?: BIT(0);
140 unsigned int link_id;
141+ bool limit_ampdu_en = mt7996_check_limit_ampdu_en(params);
142
143 for_each_set_bit(link_id, &valid_links, IEEE80211_MLD_MAX_NUM_LINKS) {
144 struct mt7996_link_sta *mlink =
145@@ -1368,6 +1448,12 @@ int mt7996_mcu_add_tx_ba(struct mt7996_dev *dev,
146 &mlink->wcid, enable, true);
147 if (ret)
148 return ret;
149+
150+ if (limit_ampdu_en) {
151+ ret = mt7996_mcu_sta_tx_cap(dev, &mconf->mt76, &mlink->wcid);
152+ if (ret)
153+ return ret;
154+ }
155 }
156
157 return 0;
158diff --git a/mt7996/mcu.h b/mt7996/mcu.h
developer05f3b2b2024-08-19 19:17:34 +0800159index 9903d88e..f9f04680 100644
developer66e89bc2024-04-23 14:50:01 +0800160--- a/mt7996/mcu.h
161+++ b/mt7996/mcu.h
developer05f3b2b2024-08-19 19:17:34 +0800162@@ -573,6 +573,13 @@ struct sta_rec_ba_uni {
developer66e89bc2024-04-23 14:50:01 +0800163 u8 __rsv[3];
164 } __packed;
165
166+struct sta_rec_tx_cap {
167+ __le16 tag;
168+ __le16 len;
169+ u8 ampdu_limit_en;
170+ u8 rsv[3];
171+} __packed;
172+
173 struct sta_rec_eht {
174 __le16 tag;
175 __le16 len;
developer05f3b2b2024-08-19 19:17:34 +0800176@@ -939,6 +946,7 @@ enum {
developer66e89bc2024-04-23 14:50:01 +0800177 sizeof(struct sta_rec_eht) + \
178 sizeof(struct sta_rec_hdrt) + \
179 sizeof(struct sta_rec_hdr_trans) + \
180+ sizeof(struct sta_rec_tx_cap) + \
181 sizeof(struct tlv))
182
183 #define MT7996_MAX_BEACON_SIZE 1338
184--
developer9237f442024-06-14 17:13:04 +08001852.18.0
developer66e89bc2024-04-23 14:50:01 +0800186