blob: 80214271aeb41ffebeb5258ff6c760ed4934b70b [file] [log] [blame]
developer064da3c2023-06-13 15:57:26 +08001From edca876e34fc2696e8f855c2d05036fa79a05f8f Mon Sep 17 00:00:00 2001
2From: Peter Chiu <chui-hao.chiu@mediatek.com>
3Date: Thu, 1 Jun 2023 12:01:10 +0800
4Subject: [PATCH 07/11] wifi: mt76: connac: add support to set ifs time by mcu
5 command
6
7There's a race between driver and fw on some tx/rx control registers
8when setting ifs, which will cause accidental hw queue pause problems.
9Avoid this by setting ifs time with bss_info mcu command.
10
11Reviewed-by: Shayne Chen <shayne.chen@mediatek.com>
12Signed-off-by: Peter Chiu <chui-hao.chiu@mediatek.com>
13Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
14Change-Id: Ib6477462a35df84a89f113a4db0e6aef5154c6a8
15---
16v2:
17 - merge two commits
18 - change bool a_band to use is_2ghz
19---
20 mt76_connac_mcu.h | 1 +
21 mt7996/mac.c | 27 ++-------------------------
22 mt7996/main.c | 5 ++---
23 mt7996/mcu.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
24 mt7996/mcu.h | 17 +++++++++++++++++
25 mt7996/mt7996.h | 3 ++-
26 6 files changed, 70 insertions(+), 29 deletions(-)
27
28diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
29index d2a3d56b..b91262ee 100644
30--- a/mt76_connac_mcu.h
31+++ b/mt76_connac_mcu.h
32@@ -1288,6 +1288,7 @@ enum {
33 UNI_BSS_INFO_UAPSD = 19,
34 UNI_BSS_INFO_PS = 21,
35 UNI_BSS_INFO_BCNFT = 22,
36+ UNI_BSS_INFO_IFS_TIME = 23,
37 UNI_BSS_INFO_OFFLOAD = 25,
38 UNI_BSS_INFO_MLD = 26,
39 };
40diff --git a/mt7996/mac.c b/mt7996/mac.c
41index 23cbfdde..2da61d2e 100644
42--- a/mt7996/mac.c
43+++ b/mt7996/mac.c
44@@ -1612,20 +1612,19 @@ void mt7996_mac_reset_counters(struct mt7996_phy *phy)
45 mt7996_mcu_get_chan_mib_info(phy, true);
46 }
47
48-void mt7996_mac_set_timing(struct mt7996_phy *phy)
49+void mt7996_mac_set_coverage_class(struct mt7996_phy *phy)
50 {
51 s16 coverage_class = phy->coverage_class;
52 struct mt7996_dev *dev = phy->dev;
53 struct mt7996_phy *phy2 = mt7996_phy2(dev);
54 struct mt7996_phy *phy3 = mt7996_phy3(dev);
55- u32 val, reg_offset;
56+ u32 reg_offset;
57 u32 cck = FIELD_PREP(MT_TIMEOUT_VAL_PLCP, 231) |
58 FIELD_PREP(MT_TIMEOUT_VAL_CCA, 48);
59 u32 ofdm = FIELD_PREP(MT_TIMEOUT_VAL_PLCP, 60) |
60 FIELD_PREP(MT_TIMEOUT_VAL_CCA, 28);
61 u8 band_idx = phy->mt76->band_idx;
62 int offset;
63- bool a_band = !(phy->mt76->chandef.chan->band == NL80211_BAND_2GHZ);
64
65 if (!test_bit(MT76_STATE_RUNNING, &phy->mt76->state))
66 return;
67@@ -1638,34 +1637,12 @@ void mt7996_mac_set_timing(struct mt7996_phy *phy)
68 coverage_class = max_t(s16, coverage_class,
69 phy3->coverage_class);
70
71- mt76_set(dev, MT_ARB_SCR(band_idx),
72- MT_ARB_SCR_TX_DISABLE | MT_ARB_SCR_RX_DISABLE);
73- udelay(1);
74-
75 offset = 3 * coverage_class;
76 reg_offset = FIELD_PREP(MT_TIMEOUT_VAL_PLCP, offset) |
77 FIELD_PREP(MT_TIMEOUT_VAL_CCA, offset);
78
79 mt76_wr(dev, MT_TMAC_CDTR(band_idx), cck + reg_offset);
80 mt76_wr(dev, MT_TMAC_ODTR(band_idx), ofdm + reg_offset);
81- mt76_wr(dev, MT_TMAC_ICR0(band_idx),
82- FIELD_PREP(MT_IFS_EIFS_OFDM, a_band ? 84 : 78) |
83- FIELD_PREP(MT_IFS_RIFS, 2) |
84- FIELD_PREP(MT_IFS_SIFS, 10) |
85- FIELD_PREP(MT_IFS_SLOT, phy->slottime));
86-
87- if (!a_band)
88- mt76_wr(dev, MT_TMAC_ICR1(band_idx),
89- FIELD_PREP(MT_IFS_EIFS_CCK, 314));
90-
91- if (phy->slottime < 20 || a_band)
92- val = MT7996_CFEND_RATE_DEFAULT;
93- else
94- val = MT7996_CFEND_RATE_11B;
95-
96- mt76_rmw_field(dev, MT_RATE_HRCR0(band_idx), MT_RATE_HRCR0_CFEND_RATE, val);
97- mt76_clear(dev, MT_ARB_SCR(band_idx),
98- MT_ARB_SCR_TX_DISABLE | MT_ARB_SCR_RX_DISABLE);
99 }
100
101 void mt7996_mac_enable_nf(struct mt7996_dev *dev, u8 band)
102diff --git a/mt7996/main.c b/mt7996/main.c
103index e7c97d2f..786c3fbc 100644
104--- a/mt7996/main.c
105+++ b/mt7996/main.c
106@@ -287,7 +287,6 @@ int mt7996_set_channel(struct mt7996_phy *phy)
107 if (ret)
108 goto out;
109
110- mt7996_mac_set_timing(phy);
111 ret = mt7996_dfs_init_radar_detector(phy);
112 mt7996_mac_cca_stats_reset(phy);
113
114@@ -564,7 +563,7 @@ static void mt7996_bss_info_changed(struct ieee80211_hw *hw,
115
116 if (slottime != phy->slottime) {
117 phy->slottime = slottime;
118- mt7996_mac_set_timing(phy);
119+ mt7996_mcu_set_timing(phy, vif);
120 }
121 }
122
123@@ -904,7 +903,7 @@ mt7996_set_coverage_class(struct ieee80211_hw *hw, s16 coverage_class)
124
125 mutex_lock(&dev->mt76.mutex);
126 phy->coverage_class = max_t(s16, coverage_class, 0);
127- mt7996_mac_set_timing(phy);
128+ mt7996_mac_set_coverage_class(phy);
129 mutex_unlock(&dev->mt76.mutex);
130 }
131
132diff --git a/mt7996/mcu.c b/mt7996/mcu.c
133index 6706d38c..0ede9769 100644
134--- a/mt7996/mcu.c
135+++ b/mt7996/mcu.c
136@@ -701,6 +701,34 @@ mt7996_mcu_muar_config(struct mt7996_phy *phy, struct ieee80211_vif *vif,
137 sizeof(req), true);
138 }
139
140+static void
141+mt7996_mcu_bss_ifs_timing_tlv(struct sk_buff *skb, struct ieee80211_vif *vif)
142+{
143+ struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
144+ struct mt7996_phy *phy = mvif->phy;
145+ struct bss_ifs_time_tlv *ifs_time;
146+ struct tlv *tlv;
147+ bool is_2ghz = phy->mt76->chandef.chan->band == NL80211_BAND_2GHZ;
148+
149+ tlv = mt7996_mcu_add_uni_tlv(skb, UNI_BSS_INFO_IFS_TIME, sizeof(*ifs_time));
150+
151+ ifs_time = (struct bss_ifs_time_tlv *)tlv;
152+ ifs_time->slot_valid = true;
153+ ifs_time->sifs_valid = true;
154+ ifs_time->rifs_valid = true;
155+ ifs_time->eifs_valid = true;
156+
157+ ifs_time->slot_time = cpu_to_le16(phy->slottime);
158+ ifs_time->sifs_time = cpu_to_le16(10);
159+ ifs_time->rifs_time = cpu_to_le16(2);
160+ ifs_time->eifs_time = cpu_to_le16(is_2ghz ? 78 : 84);
161+
162+ if (is_2ghz) {
163+ ifs_time->eifs_cck_valid = true;
164+ ifs_time->eifs_cck_time = cpu_to_le16(314);
165+ }
166+}
167+
168 static int
169 mt7996_mcu_bss_basic_tlv(struct sk_buff *skb,
170 struct ieee80211_vif *vif,
171@@ -826,6 +854,7 @@ int mt7996_mcu_add_bss_info(struct mt7996_phy *phy,
172 mt7996_mcu_bss_bmc_tlv(skb, vif, phy);
173 mt7996_mcu_bss_ra_tlv(skb, vif, phy);
174 mt7996_mcu_bss_txcmd_tlv(skb, true);
175+ mt7996_mcu_bss_ifs_timing_tlv(skb, vif);
176
177 if (vif->bss_conf.he_support)
178 mt7996_mcu_bss_he_tlv(skb, vif, phy);
179@@ -838,6 +867,23 @@ out:
180 MCU_WMWA_UNI_CMD(BSS_INFO_UPDATE), true);
181 }
182
183+int mt7996_mcu_set_timing(struct mt7996_phy *phy, struct ieee80211_vif *vif)
184+{
185+ struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
186+ struct mt7996_dev *dev = phy->dev;
187+ struct sk_buff *skb;
188+
189+ skb = __mt7996_mcu_alloc_bss_req(&dev->mt76, &mvif->mt76,
190+ MT7996_BSS_UPDATE_MAX_SIZE);
191+ if (IS_ERR(skb))
192+ return PTR_ERR(skb);
193+
194+ mt7996_mcu_bss_ifs_timing_tlv(skb, vif);
195+
196+ return mt76_mcu_skb_send_msg(&dev->mt76, skb,
197+ MCU_WMWA_UNI_CMD(BSS_INFO_UPDATE), true);
198+}
199+
200 static int
201 mt7996_mcu_sta_ba(struct mt76_dev *dev, struct mt76_vif *mvif,
202 struct ieee80211_ampdu_params *params,
203diff --git a/mt7996/mcu.h b/mt7996/mcu.h
204index d7075a4d..078f8285 100644
205--- a/mt7996/mcu.h
206+++ b/mt7996/mcu.h
207@@ -317,6 +317,22 @@ struct bss_sec_tlv {
208 u8 __rsv2[1];
209 } __packed;
210
211+struct bss_ifs_time_tlv {
212+ __le16 tag;
213+ __le16 len;
214+ u8 slot_valid;
215+ u8 sifs_valid;
216+ u8 rifs_valid;
217+ u8 eifs_valid;
218+ __le16 slot_time;
219+ __le16 sifs_time;
220+ __le16 rifs_time;
221+ __le16 eifs_time;
222+ u8 eifs_cck_valid;
223+ u8 rsv;
224+ __le16 eifs_cck_time;
225+} __packed;
226+
227 struct bss_power_save {
228 __le16 tag;
229 __le16 len;
230@@ -552,6 +568,7 @@ enum {
231 sizeof(struct bss_txcmd_tlv) + \
232 sizeof(struct bss_power_save) + \
233 sizeof(struct bss_sec_tlv) + \
234+ sizeof(struct bss_ifs_time_tlv) + \
235 sizeof(struct bss_mld_tlv))
236
237 #define MT7996_STA_UPDATE_MAX_SIZE (sizeof(struct sta_req_hdr) + \
238diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
239index 7dfdc738..42892f06 100644
240--- a/mt7996/mt7996.h
241+++ b/mt7996/mt7996.h
242@@ -463,6 +463,7 @@ int mt7996_mcu_set_radar_th(struct mt7996_dev *dev, int index,
243 const struct mt7996_dfs_pattern *pattern);
244 int mt7996_mcu_set_radio_en(struct mt7996_phy *phy, bool enable);
245 int mt7996_mcu_set_rts_thresh(struct mt7996_phy *phy, u32 val);
246+int mt7996_mcu_set_timing(struct mt7996_phy *phy, struct ieee80211_vif *vif);
247 int mt7996_mcu_get_chan_mib_info(struct mt7996_phy *phy, bool chan_switch);
248 int mt7996_mcu_rdd_cmd(struct mt7996_dev *dev, int cmd, u8 index,
249 u8 rx_sel, u8 val);
250@@ -526,7 +527,7 @@ void mt7996_mac_write_txwi(struct mt7996_dev *dev, __le32 *txwi,
251 struct sk_buff *skb, struct mt76_wcid *wcid,
252 struct ieee80211_key_conf *key, int pid,
253 enum mt76_txq_id qid, u32 changed);
254-void mt7996_mac_set_timing(struct mt7996_phy *phy);
255+void mt7996_mac_set_coverage_class(struct mt7996_phy *phy);
256 int mt7996_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
257 struct ieee80211_sta *sta);
258 void mt7996_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif,
259--
2602.39.2
261