blob: 14514e2a475d8d0809bd383679403d5e035f576d [file] [log] [blame]
developer7e2761e2023-10-12 08:11:13 +08001From d07d8b3b246b974d7ae4ad9bdfc676438cb45fec Mon Sep 17 00:00:00 2001
developer064da3c2023-06-13 15:57:26 +08002From: "Allen.Ye" <allen.ye@mediatek.com>
developerc2cfe0f2023-09-22 04:11:09 +08003Date: Mon, 10 Jul 2023 19:56:16 +0800
developer7e2761e2023-10-12 08:11:13 +08004Subject: [PATCH 48/98] wifi: mt76: mt7996: add single sku
developer064da3c2023-06-13 15:57:26 +08005
6Add single sku and default enable sku.
7
8Signed-off-by: Allen.Ye <allen.ye@mediatek.com>
9---
developerc2cfe0f2023-09-22 04:11:09 +080010 eeprom.c | 50 +++++++++++++++++++++++---
11 mt76.h | 9 +++++
developer064da3c2023-06-13 15:57:26 +080012 mt76_connac_mcu.c | 2 +-
13 mt7996/init.c | 2 ++
developerc2cfe0f2023-09-22 04:11:09 +080014 mt7996/main.c | 16 +++++++++
developer064da3c2023-06-13 15:57:26 +080015 mt7996/mcu.c | 92 +++++++++++++++++++++++++++++++++++++++++++++++
16 mt7996/mcu.h | 12 +++++++
17 mt7996/mt7996.h | 2 ++
developerc2cfe0f2023-09-22 04:11:09 +080018 8 files changed, 179 insertions(+), 6 deletions(-)
developer064da3c2023-06-13 15:57:26 +080019
20diff --git a/eeprom.c b/eeprom.c
developer7e2761e2023-10-12 08:11:13 +080021index 89bb913..bd662dd 100644
developer064da3c2023-06-13 15:57:26 +080022--- a/eeprom.c
23+++ b/eeprom.c
developerc2cfe0f2023-09-22 04:11:09 +080024@@ -356,6 +356,7 @@ mt76_apply_multi_array_limit(s8 *pwr, size_t pwr_len, s8 pwr_num,
developer064da3c2023-06-13 15:57:26 +080025 s8 mt76_get_rate_power_limits(struct mt76_phy *phy,
26 struct ieee80211_channel *chan,
27 struct mt76_power_limits *dest,
28+ struct mt76_power_path_limits *dest_path,
29 s8 target_power)
30 {
31 struct mt76_dev *dev = phy->dev;
developerc2cfe0f2023-09-22 04:11:09 +080032@@ -363,16 +364,20 @@ s8 mt76_get_rate_power_limits(struct mt76_phy *phy,
developer064da3c2023-06-13 15:57:26 +080033 const __be32 *val;
34 char name[16];
35 u32 mcs_rates = dev->drv->mcs_rates;
36- u32 ru_rates = ARRAY_SIZE(dest->ru[0]);
37 char band;
38 size_t len;
developerc2cfe0f2023-09-22 04:11:09 +080039- s8 max_power = 0;
40+ s8 max_power = -127;
41+ s8 max_power_backoff = -127;
developer064da3c2023-06-13 15:57:26 +080042 s8 txs_delta;
developerc2cfe0f2023-09-22 04:11:09 +080043+ int n_chains = hweight8(phy->antenna_mask);
44+ s8 target_power_combine = target_power + mt76_tx_power_nss_delta(n_chains);
developer064da3c2023-06-13 15:57:26 +080045
46 if (!mcs_rates)
47- mcs_rates = 10;
48+ mcs_rates = 12;
49
50 memset(dest, target_power, sizeof(*dest));
51+ if (dest_path != NULL)
52+ memset(dest_path, 0, sizeof(*dest_path));
53
54 if (!IS_ENABLED(CONFIG_OF))
55 return target_power;
developerc2cfe0f2023-09-22 04:11:09 +080056@@ -420,12 +425,47 @@ s8 mt76_get_rate_power_limits(struct mt76_phy *phy,
developer064da3c2023-06-13 15:57:26 +080057 ARRAY_SIZE(dest->mcs), val, len,
58 target_power, txs_delta, &max_power);
59
60- val = mt76_get_of_array(np, "rates-ru", &len, ru_rates + 1);
61+ val = mt76_get_of_array(np, "rates-ru", &len, ARRAY_SIZE(dest->ru[0]) + 1);
62 mt76_apply_multi_array_limit(dest->ru[0], ARRAY_SIZE(dest->ru[0]),
63 ARRAY_SIZE(dest->ru), val, len,
64 target_power, txs_delta, &max_power);
65
developerc2cfe0f2023-09-22 04:11:09 +080066- return max_power;
67+ val = mt76_get_of_array(np, "rates-eht", &len, ARRAY_SIZE(dest->eht[0]) + 1);
68+ mt76_apply_multi_array_limit(dest->eht[0], ARRAY_SIZE(dest->eht[0]),
69+ ARRAY_SIZE(dest->eht), val, len,
developer064da3c2023-06-13 15:57:26 +080070+ target_power, txs_delta, &max_power);
71+
72+ if (dest_path == NULL)
73+ return max_power;
74+
developerc2cfe0f2023-09-22 04:11:09 +080075+ max_power_backoff = max_power;
76+
developer064da3c2023-06-13 15:57:26 +080077+ val = mt76_get_of_array(np, "paths-cck", &len, ARRAY_SIZE(dest_path->cck));
78+ mt76_apply_array_limit(dest_path->cck, ARRAY_SIZE(dest_path->cck), val,
developerc2cfe0f2023-09-22 04:11:09 +080079+ target_power_combine, txs_delta, &max_power_backoff);
developer064da3c2023-06-13 15:57:26 +080080+
81+ val = mt76_get_of_array(np, "paths-ofdm", &len, ARRAY_SIZE(dest_path->ofdm));
82+ mt76_apply_array_limit(dest_path->ofdm, ARRAY_SIZE(dest_path->ofdm), val,
developerc2cfe0f2023-09-22 04:11:09 +080083+ target_power_combine, txs_delta, &max_power_backoff);
developer064da3c2023-06-13 15:57:26 +080084+
85+ val = mt76_get_of_array(np, "paths-ofdm-bf", &len, ARRAY_SIZE(dest_path->ofdm_bf));
86+ mt76_apply_array_limit(dest_path->ofdm_bf, ARRAY_SIZE(dest_path->ofdm_bf), val,
developerc2cfe0f2023-09-22 04:11:09 +080087+ target_power_combine, txs_delta, &max_power_backoff);
developer064da3c2023-06-13 15:57:26 +080088+
89+ val = mt76_get_of_array(np, "paths-ru", &len, ARRAY_SIZE(dest_path->ru[0]) + 1);
90+ mt76_apply_multi_array_limit(dest_path->ru[0], ARRAY_SIZE(dest_path->ru[0]),
91+ ARRAY_SIZE(dest_path->ru), val, len,
developerc2cfe0f2023-09-22 04:11:09 +080092+ target_power_combine, txs_delta, &max_power_backoff);
developer064da3c2023-06-13 15:57:26 +080093+
94+ val = mt76_get_of_array(np, "paths-ru-bf", &len, ARRAY_SIZE(dest_path->ru_bf[0]) + 1);
95+ mt76_apply_multi_array_limit(dest_path->ru_bf[0], ARRAY_SIZE(dest_path->ru_bf[0]),
96+ ARRAY_SIZE(dest_path->ru_bf), val, len,
developerc2cfe0f2023-09-22 04:11:09 +080097+ target_power_combine, txs_delta, &max_power_backoff);
98+
99+ if (max_power_backoff == target_power_combine)
100+ return max_power;
developer064da3c2023-06-13 15:57:26 +0800101+
developerc2cfe0f2023-09-22 04:11:09 +0800102+ return max_power_backoff;
developer064da3c2023-06-13 15:57:26 +0800103 }
104 EXPORT_SYMBOL_GPL(mt76_get_rate_power_limits);
developerc2cfe0f2023-09-22 04:11:09 +0800105
developer064da3c2023-06-13 15:57:26 +0800106diff --git a/mt76.h b/mt76.h
developer7e2761e2023-10-12 08:11:13 +0800107index 0096c7f..d59a1f5 100644
developer064da3c2023-06-13 15:57:26 +0800108--- a/mt76.h
109+++ b/mt76.h
developer7e2761e2023-10-12 08:11:13 +0800110@@ -1060,6 +1060,14 @@ struct mt76_power_limits {
developerc2cfe0f2023-09-22 04:11:09 +0800111 s8 eht[16][16];
112 };
113
developer064da3c2023-06-13 15:57:26 +0800114+struct mt76_power_path_limits {
115+ s8 cck[5];
116+ s8 ofdm[5];
117+ s8 ofdm_bf[4];
118+ s8 ru[16][15];
119+ s8 ru_bf[16][15];
developerc2cfe0f2023-09-22 04:11:09 +0800120+};
121+
developer064da3c2023-06-13 15:57:26 +0800122 struct mt76_ethtool_worker_info {
developerc2cfe0f2023-09-22 04:11:09 +0800123 u64 *data;
124 int idx;
developer7e2761e2023-10-12 08:11:13 +0800125@@ -1655,6 +1663,7 @@ void mt76_set_irq_mask(struct mt76_dev *dev, u32 addr, u32 clear, u32 set);
developer064da3c2023-06-13 15:57:26 +0800126 s8 mt76_get_rate_power_limits(struct mt76_phy *phy,
127 struct ieee80211_channel *chan,
128 struct mt76_power_limits *dest,
129+ struct mt76_power_path_limits *dest_path,
130 s8 target_power);
131
developer7e2761e2023-10-12 08:11:13 +0800132 static inline bool mt76_queue_is_wed_tx_free(struct mt76_queue *q)
developer064da3c2023-06-13 15:57:26 +0800133diff --git a/mt76_connac_mcu.c b/mt76_connac_mcu.c
developer7e2761e2023-10-12 08:11:13 +0800134index 236cfea..214a526 100644
developer064da3c2023-06-13 15:57:26 +0800135--- a/mt76_connac_mcu.c
136+++ b/mt76_connac_mcu.c
developerc2cfe0f2023-09-22 04:11:09 +0800137@@ -2269,7 +2269,7 @@ mt76_connac_mcu_rate_txpower_band(struct mt76_phy *phy,
developer064da3c2023-06-13 15:57:26 +0800138 sar_power = mt76_get_sar_power(phy, &chan, reg_power);
139
developerc2cfe0f2023-09-22 04:11:09 +0800140 mt76_get_rate_power_limits(phy, &chan, limits,
developer064da3c2023-06-13 15:57:26 +0800141- sar_power);
142+ NULL, sar_power);
143
144 tx_power_tlv.last_msg = ch_list[idx] == last_ch;
145 sku_tlbv.channel = ch_list[idx];
146diff --git a/mt7996/init.c b/mt7996/init.c
developer7e2761e2023-10-12 08:11:13 +0800147index bf3479e..ad93927 100644
developer064da3c2023-06-13 15:57:26 +0800148--- a/mt7996/init.c
149+++ b/mt7996/init.c
developer7e2761e2023-10-12 08:11:13 +0800150@@ -295,6 +295,7 @@ void mt7996_init_txpower(struct mt7996_dev *dev,
developer064da3c2023-06-13 15:57:26 +0800151 int nss_delta = mt76_tx_power_nss_delta(nss);
152 int pwr_delta = mt7996_eeprom_get_power_delta(dev, sband->band);
153 struct mt76_power_limits limits;
154+ struct mt76_power_path_limits limits_path;
155
156 for (i = 0; i < sband->n_channels; i++) {
157 struct ieee80211_channel *chan = &sband->channels[i];
developer7e2761e2023-10-12 08:11:13 +0800158@@ -303,6 +304,7 @@ void mt7996_init_txpower(struct mt7996_dev *dev,
developer064da3c2023-06-13 15:57:26 +0800159 target_power += pwr_delta;
160 target_power = mt76_get_rate_power_limits(&dev->mphy, chan,
161 &limits,
162+ &limits_path,
163 target_power);
164 target_power += nss_delta;
165 target_power = DIV_ROUND_UP(target_power, 2);
166diff --git a/mt7996/main.c b/mt7996/main.c
developer7e2761e2023-10-12 08:11:13 +0800167index 0ea006c..9e3e4ed 100644
developer064da3c2023-06-13 15:57:26 +0800168--- a/mt7996/main.c
169+++ b/mt7996/main.c
170@@ -77,6 +77,15 @@ int mt7996_run(struct ieee80211_hw *hw)
171 if (ret)
172 goto out;
173
174+#ifdef CONFIG_MTK_DEBUG
175+ ret = mt7996_mcu_set_tx_power_ctrl(phy, UNI_TXPOWER_SKU_POWER_LIMIT_CTRL,
176+ !dev->dbg.sku_disable);
177+#else
178+ ret = mt7996_mcu_set_tx_power_ctrl(phy, UNI_TXPOWER_SKU_POWER_LIMIT_CTRL, true);
179+#endif
180+ if (ret)
181+ goto out;
182+
183 set_bit(MT76_STATE_RUNNING, &phy->mt76->state);
184
185 ieee80211_queue_delayed_work(hw, &phy->mt76->mac_work,
developerc2cfe0f2023-09-22 04:11:09 +0800186@@ -429,6 +438,12 @@ static int mt7996_config(struct ieee80211_hw *hw, u32 changed)
developer064da3c2023-06-13 15:57:26 +0800187 ieee80211_wake_queues(hw);
188 }
189
190+ if (changed & IEEE80211_CONF_CHANGE_POWER) {
191+ ret = mt7996_mcu_set_txpower_sku(phy);
192+ if (ret)
193+ return ret;
194+ }
195+
196 mutex_lock(&dev->mt76.mutex);
197
198 if (changed & IEEE80211_CONF_CHANGE_MONITOR) {
developerc2cfe0f2023-09-22 04:11:09 +0800199@@ -1005,6 +1020,7 @@ mt7996_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant)
200 mt76_set_stream_caps(phy->mt76, true);
201 mt7996_set_stream_vht_txbf_caps(phy);
202 mt7996_set_stream_he_eht_caps(phy);
203+ mt7996_mcu_set_txpower_sku(phy);
204
205 mutex_unlock(&dev->mt76.mutex);
206
developer064da3c2023-06-13 15:57:26 +0800207diff --git a/mt7996/mcu.c b/mt7996/mcu.c
developer7e2761e2023-10-12 08:11:13 +0800208index 1a1c732..c87cb1a 100644
developer064da3c2023-06-13 15:57:26 +0800209--- a/mt7996/mcu.c
210+++ b/mt7996/mcu.c
developer7e2761e2023-10-12 08:11:13 +0800211@@ -4708,6 +4708,98 @@ int mt7996_mcu_set_scs(struct mt7996_phy *phy, u8 enable)
developer064da3c2023-06-13 15:57:26 +0800212 &req, sizeof(req), false);
213 }
214
215+int mt7996_mcu_set_txpower_sku(struct mt7996_phy *phy)
216+{
217+#define TX_POWER_LIMIT_TABLE_RATE 0
218+#define TX_POWER_LIMIT_TABLE_PATH 1
219+ struct mt7996_dev *dev = phy->dev;
220+ struct mt76_phy *mphy = phy->mt76;
221+ struct ieee80211_hw *hw = mphy->hw;
222+ struct tx_power_limit_table_ctrl {
223+ u8 __rsv1[4];
224+
225+ __le16 tag;
226+ __le16 len;
227+ u8 power_ctrl_id;
228+ u8 power_limit_type;
229+ u8 band_idx;
230+ } __packed req = {
231+ .tag = cpu_to_le16(UNI_TXPOWER_POWER_LIMIT_TABLE_CTRL),
232+ .len = cpu_to_le16(sizeof(req) + MT7996_SKU_PATH_NUM - 4),
233+ .power_ctrl_id = UNI_TXPOWER_POWER_LIMIT_TABLE_CTRL,
234+ .power_limit_type = TX_POWER_LIMIT_TABLE_RATE,
235+ .band_idx = phy->mt76->band_idx,
236+ };
237+
238+ int i, ret, tx_power;
239+ const u8 *len = mt7996_sku_group_len;
240+ struct mt76_power_limits la = {};
241+ struct mt76_power_path_limits la_path = {};
242+ struct sk_buff *skb;
243+
244+ tx_power = mt7996_get_power_bound(phy, hw->conf.power_level);
245+ tx_power = mt76_get_rate_power_limits(mphy, mphy->chandef.chan,
246+ &la, &la_path, tx_power);
247+ mphy->txpower_cur = tx_power;
248+
249+ skb = mt76_mcu_msg_alloc(&dev->mt76, NULL,
250+ sizeof(req) + MT7996_SKU_PATH_NUM);
251+ if (!skb)
252+ return -ENOMEM;
253+
254+ skb_put_data(skb, &req, sizeof(req));
255+ skb_put_data(skb, &la.cck, len[SKU_CCK] + len[SKU_OFDM]);
256+
257+ skb_put_data(skb, &la.mcs[0], len[SKU_HT20]);
258+ skb_put_data(skb, &la.mcs[1], len[SKU_HT40]);
259+
260+ /* vht */
261+ for (i = 0; i < 4; i++) {
262+ skb_put_data(skb, &la.mcs[i], sizeof(la.mcs[i]));
263+ skb_put_zero(skb, 2); /* padding */
264+ }
265+
266+ /* he */
267+ skb_put_data(skb, &la.ru[0], sizeof(la.ru));
268+
269+ /* eht */
developerc2cfe0f2023-09-22 04:11:09 +0800270+ skb_put_data(skb, &la.eht[0], sizeof(la.eht));
developer064da3c2023-06-13 15:57:26 +0800271+
272+ /* padding */
273+ skb_put_zero(skb, MT7996_SKU_PATH_NUM - MT7996_SKU_RATE_NUM);
274+
275+ ret = mt76_mcu_skb_send_msg(&dev->mt76, skb,
276+ MCU_WM_UNI_CMD(TXPOWER), true);
277+ if (ret)
278+ return ret;
279+
280+ /* only set per-path power table when it's configured */
281+ if (!la_path.ofdm[0])
282+ return 0;
283+
284+ skb = mt76_mcu_msg_alloc(&dev->mt76, NULL,
285+ sizeof(req) + MT7996_SKU_PATH_NUM);
286+ if (!skb)
287+ return -ENOMEM;
288+ req.power_limit_type = TX_POWER_LIMIT_TABLE_PATH;
289+
290+ skb_put_data(skb, &req, sizeof(req));
291+ skb_put_data(skb, &la_path.cck, sizeof(la_path.cck));
292+ skb_put_data(skb, &la_path.ofdm, sizeof(la_path.ofdm));
293+ skb_put_data(skb, &la_path.ofdm_bf, sizeof(la_path.ofdm_bf));
294+
295+ for (i = 0; i < 32; i++) {
296+ bool bf = i % 2;
297+ u8 idx = i / 2;
298+ s8 *buf = bf ? la_path.ru_bf[idx] : la_path.ru[idx];
299+
300+ skb_put_data(skb, buf, sizeof(la_path.ru[0]));
301+ }
302+
303+ return mt76_mcu_skb_send_msg(&dev->mt76, skb,
304+ MCU_WM_UNI_CMD(TXPOWER), true);
305+}
306+
307 #ifdef CONFIG_MTK_VENDOR
308 void mt7996_set_wireless_vif(void *data, u8 *mac, struct ieee80211_vif *vif)
309 {
310diff --git a/mt7996/mcu.h b/mt7996/mcu.h
developer7e2761e2023-10-12 08:11:13 +0800311index 7808c35..6fc5ab3 100644
developer064da3c2023-06-13 15:57:26 +0800312--- a/mt7996/mcu.h
313+++ b/mt7996/mcu.h
developer7e2761e2023-10-12 08:11:13 +0800314@@ -777,6 +777,18 @@ enum {
developer064da3c2023-06-13 15:57:26 +0800315 #define MT7996_MAX_BSS_OFFLOAD_SIZE (MT7996_MAX_BEACON_SIZE + \
316 MT7996_BEACON_UPDATE_SIZE)
317
318+static inline s8
319+mt7996_get_power_bound(struct mt7996_phy *phy, s8 txpower)
320+{
321+ struct mt76_phy *mphy = phy->mt76;
322+ int n_chains = hweight8(mphy->antenna_mask);
323+
324+ txpower = mt76_get_sar_power(mphy, mphy->chandef.chan, txpower * 2);
325+ txpower -= mt76_tx_power_nss_delta(n_chains);
326+
327+ return txpower;
328+}
329+
330 enum {
331 UNI_BAND_CONFIG_RADIO_ENABLE,
332 UNI_BAND_CONFIG_RTS_THRESHOLD = 0x08,
333diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
developer7e2761e2023-10-12 08:11:13 +0800334index 7269076..34c8fe6 100644
developer064da3c2023-06-13 15:57:26 +0800335--- a/mt7996/mt7996.h
336+++ b/mt7996/mt7996.h
developer7e2761e2023-10-12 08:11:13 +0800337@@ -64,6 +64,7 @@
developer064da3c2023-06-13 15:57:26 +0800338 #define MT7996_BUILD_TIME_LEN 24
339
340 #define MT7996_SKU_RATE_NUM 417
341+#define MT7996_SKU_PATH_NUM 494
342
developer7e2761e2023-10-12 08:11:13 +0800343 #define MT7996_RRO_MAX_SESSION 1024
344 #define MT7996_RRO_WINDOW_MAX_LEN 1024
345@@ -614,6 +615,7 @@ int mt7996_mcu_set_tx_power_ctrl(struct mt7996_phy *phy, u8 power_ctrl_id, u8 da
developer064da3c2023-06-13 15:57:26 +0800346 int mt7996_mcu_get_tx_power_info(struct mt7996_phy *phy, u8 category, void *event);
347 int mt7996_mcu_apply_group_cal(struct mt7996_dev *dev);
348 int mt7996_mcu_apply_tx_dpd(struct mt7996_phy *phy);
349+int mt7996_mcu_set_txpower_sku(struct mt7996_phy *phy);
350 int mt7996_mcu_set_scs(struct mt7996_phy *phy, u8 enable);
351 void mt7996_mcu_scs_sta_poll(struct work_struct *work);
352 #ifdef CONFIG_NL80211_TESTMODE
353--
developer7e2761e2023-10-12 08:11:13 +08003542.18.0
developer064da3c2023-06-13 15:57:26 +0800355