blob: 5dc8109cb7096e715936f74cefe31aff0db58736 [file] [log] [blame]
developer064da3c2023-06-13 15:57:26 +08001From de92f88f5c00cf1069df00bb89f50281b0b2d05e Mon Sep 17 00:00:00 2001
2From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
3Date: Fri, 12 May 2023 16:24:53 +0800
4Subject: [PATCH 37/39] wifi: mt76: mt7996: add beacon duplicate tx mode
5 support
6
7Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
8---
9 mt76_connac_mcu.h | 1 +
10 mt7996/init.c | 6 ++++--
11 mt7996/mac.c | 11 -----------
12 mt7996/main.c | 18 +++++++++---------
13 mt7996/mcu.c | 30 ++++++++++++++++++++++++++++++
14 mt7996/mcu.h | 20 ++++++++++++++++++++
15 mt7996/mt7996.h | 8 +++++---
16 7 files changed, 69 insertions(+), 25 deletions(-)
17
18diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
19index bfec420..4bb9508 100644
20--- a/mt76_connac_mcu.h
21+++ b/mt76_connac_mcu.h
22@@ -1224,6 +1224,7 @@ enum {
23 MCU_UNI_CMD_CHANNEL_SWITCH = 0x34,
24 MCU_UNI_CMD_THERMAL = 0x35,
25 MCU_UNI_CMD_VOW = 0x37,
26+ MCU_UNI_CMD_FIXED_RATE_TABLE = 0x40,
27 MCU_UNI_CMD_TESTMODE_CTRL = 0x46,
28 MCU_UNI_CMD_RRO = 0x57,
29 MCU_UNI_CMD_OFFCH_SCAN_CTRL = 0x58,
30diff --git a/mt7996/init.c b/mt7996/init.c
31index 1072874..9eba689 100644
32--- a/mt7996/init.c
33+++ b/mt7996/init.c
34@@ -351,6 +351,7 @@ mt7996_init_wiphy(struct ieee80211_hw *hw)
35 IEEE80211_RADIOTAP_TIMESTAMP_UNIT_US;
36
37 phy->slottime = 9;
38+ phy->beacon_rate = -1;
39
40 hw->sta_data_size = sizeof(struct mt7996_sta);
41 hw->vif_data_size = sizeof(struct mt7996_vif);
42@@ -459,11 +460,12 @@ static void mt7996_mac_init_basic_rates(struct mt7996_dev *dev)
43
44 for (i = 0; i < ARRAY_SIZE(mt76_rates); i++) {
45 u16 rate = mt76_rates[i].hw_value;
46- u16 idx = MT7996_BASIC_RATES_TBL + i;
47+ /* odd index for driver, even index for firmware */
48+ u16 idx = MT7996_BASIC_RATES_TBL + 2 * i;
49
50 rate = FIELD_PREP(MT_TX_RATE_MODE, rate >> 8) |
51 FIELD_PREP(MT_TX_RATE_IDX, rate & GENMASK(7, 0));
52- mt7996_mac_set_fixed_rate_table(dev, idx, rate);
53+ mt7996_mcu_set_fixed_rate_table(&dev->phy, idx, rate, false);
54 }
55 }
56
57diff --git a/mt7996/mac.c b/mt7996/mac.c
58index 724af82..05269e7 100644
59--- a/mt7996/mac.c
60+++ b/mt7996/mac.c
61@@ -252,17 +252,6 @@ void mt7996_mac_enable_rtscts(struct mt7996_dev *dev,
62 mt76_clear(dev, addr, BIT(5));
63 }
64
65-void mt7996_mac_set_fixed_rate_table(struct mt7996_dev *dev,
66- u8 tbl_idx, u16 rate_idx)
67-{
68- u32 ctrl = MT_WTBL_ITCR_WR | MT_WTBL_ITCR_EXEC | tbl_idx;
69-
70- mt76_wr(dev, MT_WTBL_ITDR0, rate_idx);
71- /* use wtbl spe idx */
72- mt76_wr(dev, MT_WTBL_ITDR1, MT_WTBL_SPE_IDX_SEL);
73- mt76_wr(dev, MT_WTBL_ITCR, ctrl);
74-}
75-
76 static void
77 mt7996_mac_decode_he_radiotap_ru(struct mt76_rx_status *status,
78 struct ieee80211_radiotap_he *he,
79diff --git a/mt7996/main.c b/mt7996/main.c
80index 20b89a7..2ed66e6 100644
81--- a/mt7996/main.c
82+++ b/mt7996/main.c
83@@ -544,24 +544,25 @@ mt7996_get_rates_table(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
84 struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
85 struct mt76_phy *mphy = hw->priv;
86 u16 rate;
87- u8 i, idx, ht;
88+ u8 i, idx;
89
90 rate = mt76_connac2_mac_tx_rate_val(mphy, vif, beacon, mcast);
91- ht = FIELD_GET(MT_TX_RATE_MODE, rate) > MT_PHY_TYPE_OFDM;
92
93- if (beacon && ht) {
94- struct mt7996_dev *dev = mt7996_hw_dev(hw);
95+ if (beacon) {
96+ struct mt7996_phy *phy = mt7996_hw_phy(hw);
97+
98+ /* odd index for driver, even index for firmware */
99+ idx = MT7996_BEACON_RATES_TBL + 2 * phy->mt76->band_idx;
100+ if (phy->beacon_rate != rate)
101+ mt7996_mcu_set_fixed_rate_table(phy, idx, rate, beacon);
102
103- /* must odd index */
104- idx = MT7996_BEACON_RATES_TBL + 2 * (mvif->mt76.idx % 20);
105- mt7996_mac_set_fixed_rate_table(dev, idx, rate);
106 return idx;
107 }
108
109 idx = FIELD_GET(MT_TX_RATE_IDX, rate);
110 for (i = 0; i < ARRAY_SIZE(mt76_rates); i++)
111 if ((mt76_rates[i].hw_value & GENMASK(7, 0)) == idx)
112- return MT7996_BASIC_RATES_TBL + i;
113+ return MT7996_BASIC_RATES_TBL + 2 * i;
114
115 return mvif->basic_rates_idx;
116 }
117@@ -965,7 +966,6 @@ mt7996_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant)
118 mt7996_set_stream_vht_txbf_caps(phy);
119 mt7996_set_stream_he_eht_caps(phy);
120
121- /* TODO: update bmc_wtbl spe_idx when antenna changes */
122 mutex_unlock(&dev->mt76.mutex);
123
124 return 0;
125diff --git a/mt7996/mcu.c b/mt7996/mcu.c
126index a5c473a..b34c6b7 100644
127--- a/mt7996/mcu.c
128+++ b/mt7996/mcu.c
129@@ -4056,6 +4056,36 @@ int mt7996_mcu_wtbl_update_hdr_trans(struct mt7996_dev *dev,
130 MCU_WMWA_UNI_CMD(STA_REC_UPDATE), true);
131 }
132
133+int mt7996_mcu_set_fixed_rate_table(struct mt7996_phy *phy, u8 table_idx,
134+ u16 rate_idx, bool beacon)
135+{
136+#define UNI_FIXED_RATE_TABLE_SET 0
137+#define SPE_IXD_SELECT_TXD 0
138+#define SPE_IXD_SELECT_BMC_WTBL 1
139+ struct mt7996_dev *dev = phy->dev;
140+ struct fixed_rate_table_ctrl req = {
141+ .tag = cpu_to_le16(UNI_FIXED_RATE_TABLE_SET),
142+ .len = cpu_to_le16(sizeof(req) - 4),
143+ .table_idx = table_idx,
144+ .rate_idx = cpu_to_le16(rate_idx),
145+ .gi = 1,
146+ .he_ltf = 1,
147+ };
148+ u8 band_idx = phy->mt76->band_idx;
149+
150+ if (beacon) {
151+ req.spe_idx_sel = SPE_IXD_SELECT_TXD;
152+ req.spe_idx = 24 + band_idx;
153+ phy->beacon_rate = rate_idx;
154+ } else {
155+ req.spe_idx_sel = SPE_IXD_SELECT_BMC_WTBL;
156+ req.spe_idx = 0;
157+ }
158+
159+ return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(FIXED_RATE_TABLE),
160+ &req, sizeof(req), false);
161+}
162+
163 int mt7996_mcu_rf_regval(struct mt7996_dev *dev, u32 regidx, u32 *val, bool set)
164 {
165 struct {
166diff --git a/mt7996/mcu.h b/mt7996/mcu.h
167index eb63441..e32767e 100644
168--- a/mt7996/mcu.h
169+++ b/mt7996/mcu.h
170@@ -771,4 +771,24 @@ enum {
171 #define MT7996_SEC_KEY_IDX GENMASK(2, 1)
172 #define MT7996_SEC_IV BIT(3)
173
174+struct fixed_rate_table_ctrl {
175+ u8 _rsv[4];
176+
177+ __le16 tag;
178+ __le16 len;
179+
180+ u8 table_idx;
181+ u8 antenna_idx;
182+ __le16 rate_idx;
183+ u8 spe_idx_sel;
184+ u8 spe_idx;
185+ u8 gi;
186+ u8 he_ltf;
187+ bool ldpc;
188+ bool txbf;
189+ bool dynamic_bw;
190+
191+ u8 rsv[1];
192+} __packed;
193+
194 #endif
195diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
196index f78f1fd..286fc1e 100644
197--- a/mt7996/mt7996.h
198+++ b/mt7996/mt7996.h
199@@ -48,7 +48,7 @@
200 #define MT7996_MAX_QUEUE (__MT_RXQ_MAX + __MT_MCUQ_MAX + 3)
201
202 /* NOTE: used to map mt76_rates. idx may change if firmware expands table */
203-#define MT7996_BASIC_RATES_TBL 11
204+#define MT7996_BASIC_RATES_TBL 31
205 #define MT7996_BEACON_RATES_TBL 25
206
207 #define MT7996_THERMAL_THROTTLE_MAX 100
208@@ -256,6 +256,8 @@ struct mt7996_phy {
209
210 u8 rdd_state;
211
212+ u16 beacon_rate;
213+
214 u32 rx_ampdu_ts;
215 u32 ampdu_ref;
216
217@@ -539,6 +541,8 @@ int mt7996_mcu_rdd_cmd(struct mt7996_dev *dev, int cmd, u8 index,
218 u8 rx_sel, u8 val);
219 int mt7996_mcu_rdd_background_enable(struct mt7996_phy *phy,
220 struct cfg80211_chan_def *chandef);
221+int mt7996_mcu_set_fixed_rate_table(struct mt7996_phy *phy, u8 table_idx,
222+ u16 rate_idx, bool beacon);
223 int mt7996_mcu_rf_regval(struct mt7996_dev *dev, u32 regidx, u32 *val, bool set);
224 int mt7996_mcu_set_hdr_trans(struct mt7996_dev *dev, bool hdr_trans);
225 int mt7996_mcu_set_rro(struct mt7996_dev *dev, u16 tag, u8 val);
226@@ -606,8 +610,6 @@ void mt7996_mac_cca_stats_reset(struct mt7996_phy *phy);
227 void mt7996_mac_enable_nf(struct mt7996_dev *dev, u8 band);
228 void mt7996_mac_enable_rtscts(struct mt7996_dev *dev,
229 struct ieee80211_vif *vif, bool enable);
230-void mt7996_mac_set_fixed_rate_table(struct mt7996_dev *dev,
231- u8 tbl_idx, u16 rate_idx);
232 void mt7996_mac_write_txwi(struct mt7996_dev *dev, __le32 *txwi,
233 struct sk_buff *skb, struct mt76_wcid *wcid,
234 struct ieee80211_key_conf *key, int pid,
235--
2362.18.0
237