blob: 100d631bfea4daff26eda4721f8697a480c63f3e [file] [log] [blame]
developer05f3b2b2024-08-19 19:17:34 +08001From 94af1c45316f8510f60afd0348918345757f1c20 Mon Sep 17 00:00:00 2001
developera16be1f2022-12-14 13:09:20 +08002From: Shayne Chen <shayne.chen@mediatek.com>
3Date: Mon, 5 Dec 2022 18:21:51 +0800
developer05f3b2b2024-08-19 19:17:34 +08004Subject: [PATCH 1022/1052] wifi: mt76: mt7915: add bf backoff limit table
developera20cdc22024-05-31 18:57:31 +08005 support
developera16be1f2022-12-14 13:09:20 +08006
7Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
8---
developereb155692024-01-11 14:08:37 +08009 debugfs.c | 4 +-
developer2cd12162024-04-18 17:29:00 +080010 eeprom.c | 38 ++++++++--
developera16be1f2022-12-14 13:09:20 +080011 mt76.h | 8 +++
developereb155692024-01-11 14:08:37 +080012 mt7915/debugfs.c | 73 +++++++++++++++++--
developer70180b02023-11-14 17:01:47 +080013 mt7915/init.c | 7 ++
developereb155692024-01-11 14:08:37 +080014 mt7915/main.c | 6 +-
15 mt7915/mcu.c | 178 +++++++++++++++++++++++++++++++++++++----------
developer70180b02023-11-14 17:01:47 +080016 mt7915/mcu.h | 6 ++
17 mt7915/mt7915.h | 9 ++-
developer2cd12162024-04-18 17:29:00 +080018 9 files changed, 275 insertions(+), 54 deletions(-)
developera16be1f2022-12-14 13:09:20 +080019
developerf9b00212023-07-31 12:27:06 +080020diff --git a/debugfs.c b/debugfs.c
developer05f3b2b2024-08-19 19:17:34 +080021index 1c8328d5..a626f7cf 100644
developerf9b00212023-07-31 12:27:06 +080022--- a/debugfs.c
23+++ b/debugfs.c
developereb155692024-01-11 14:08:37 +080024@@ -95,9 +95,9 @@ void mt76_seq_puts_array(struct seq_file *file, const char *str,
developerf9b00212023-07-31 12:27:06 +080025 {
26 int i;
27
28- seq_printf(file, "%10s:", str);
29+ seq_printf(file, "%16s:", str);
30 for (i = 0; i < len; i++)
developereb155692024-01-11 14:08:37 +080031- seq_printf(file, " %2d", val[i]);
32+ seq_printf(file, " %4d", val[i]);
developerf9b00212023-07-31 12:27:06 +080033 seq_puts(file, "\n");
developereb155692024-01-11 14:08:37 +080034 }
35 EXPORT_SYMBOL_GPL(mt76_seq_puts_array);
developera16be1f2022-12-14 13:09:20 +080036diff --git a/eeprom.c b/eeprom.c
developer05f3b2b2024-08-19 19:17:34 +080037index 9d029c04..aa33e7b5 100644
developera16be1f2022-12-14 13:09:20 +080038--- a/eeprom.c
39+++ b/eeprom.c
developereb155692024-01-11 14:08:37 +080040@@ -336,9 +336,10 @@ mt76_apply_array_limit(s8 *pwr, size_t pwr_len, const __be32 *data,
developer70180b02023-11-14 17:01:47 +080041 static void
42 mt76_apply_multi_array_limit(s8 *pwr, size_t pwr_len, s8 pwr_num,
43 const __be32 *data, size_t len, s8 target_power,
44- s8 nss_delta, s8 *max_power)
45+ s8 nss_delta)
46 {
47 int i, cur;
48+ s8 max_power = -128;
49
50 if (!data)
51 return;
developereb155692024-01-11 14:08:37 +080052@@ -350,7 +351,7 @@ mt76_apply_multi_array_limit(s8 *pwr, size_t pwr_len, s8 pwr_num,
developer70180b02023-11-14 17:01:47 +080053 break;
54
55 mt76_apply_array_limit(pwr + pwr_len * i, pwr_len, data + 1,
56- target_power, nss_delta, max_power);
57+ target_power, nss_delta, &max_power);
58 if (--cur > 0)
59 continue;
60
developereb155692024-01-11 14:08:37 +080061@@ -377,12 +378,16 @@ s8 mt76_get_rate_power_limits(struct mt76_phy *phy,
developer327aa322023-07-10 13:49:56 +080062 char band;
63 size_t len;
developerc8796032023-08-09 10:28:15 +080064 s8 max_power = -127;
developer327aa322023-07-10 13:49:56 +080065+ s8 max_power_backoff = -127;
66 s8 txs_delta;
developerf9b00212023-07-31 12:27:06 +080067+ int n_chains = hweight16(phy->chainmask);
developer327aa322023-07-10 13:49:56 +080068+ s8 target_power_combine = target_power + mt76_tx_power_nss_delta(n_chains);
69
developera16be1f2022-12-14 13:09:20 +080070 if (!mcs_rates)
71 mcs_rates = 10;
72
73- memset(dest, target_power, sizeof(*dest));
74+ memset(dest, target_power, sizeof(*dest) - sizeof(dest->path));
75+ memset(&dest->path, 0, sizeof(dest->path));
76
77 if (!IS_ENABLED(CONFIG_OF))
78 return target_power;
developer2cd12162024-04-18 17:29:00 +080079@@ -428,12 +433,35 @@ s8 mt76_get_rate_power_limits(struct mt76_phy *phy,
developer70180b02023-11-14 17:01:47 +080080 val = mt76_get_of_array(np, "rates-mcs", &len, mcs_rates + 1);
81 mt76_apply_multi_array_limit(dest->mcs[0], ARRAY_SIZE(dest->mcs[0]),
82 ARRAY_SIZE(dest->mcs), val, len,
83- target_power, txs_delta, &max_power);
84+ target_power, txs_delta);
85
86 val = mt76_get_of_array(np, "rates-ru", &len, ru_rates + 1);
87 mt76_apply_multi_array_limit(dest->ru[0], ARRAY_SIZE(dest->ru[0]),
developera16be1f2022-12-14 13:09:20 +080088 ARRAY_SIZE(dest->ru), val, len,
developer70180b02023-11-14 17:01:47 +080089- target_power, txs_delta, &max_power);
90+ target_power, txs_delta);
developer2cd12162024-04-18 17:29:00 +080091+
developer327aa322023-07-10 13:49:56 +080092+ max_power_backoff = max_power;
developera16be1f2022-12-14 13:09:20 +080093+ val = mt76_get_of_array(np, "paths-cck", &len, ARRAY_SIZE(dest->path.cck));
94+ mt76_apply_array_limit(dest->path.cck, ARRAY_SIZE(dest->path.cck), val,
developer327aa322023-07-10 13:49:56 +080095+ target_power_combine, txs_delta, &max_power_backoff);
developera16be1f2022-12-14 13:09:20 +080096+
97+ val = mt76_get_of_array(np, "paths-ofdm", &len, ARRAY_SIZE(dest->path.ofdm));
98+ mt76_apply_array_limit(dest->path.ofdm, ARRAY_SIZE(dest->path.ofdm), val,
developer327aa322023-07-10 13:49:56 +080099+ target_power_combine, txs_delta, &max_power_backoff);
developera16be1f2022-12-14 13:09:20 +0800100+
101+ val = mt76_get_of_array(np, "paths-ofdm-bf", &len, ARRAY_SIZE(dest->path.ofdm_bf));
102+ mt76_apply_array_limit(dest->path.ofdm_bf, ARRAY_SIZE(dest->path.ofdm_bf), val,
developer327aa322023-07-10 13:49:56 +0800103+ target_power_combine, txs_delta, &max_power_backoff);
developera16be1f2022-12-14 13:09:20 +0800104+
105+ val = mt76_get_of_array(np, "paths-ru", &len, ARRAY_SIZE(dest->path.ru[0]) + 1);
106+ mt76_apply_multi_array_limit(dest->path.ru[0], ARRAY_SIZE(dest->path.ru[0]),
107+ ARRAY_SIZE(dest->path.ru), val, len,
developer70180b02023-11-14 17:01:47 +0800108+ target_power_combine, txs_delta);
developera16be1f2022-12-14 13:09:20 +0800109+
110+ val = mt76_get_of_array(np, "paths-ru-bf", &len, ARRAY_SIZE(dest->path.ru_bf[0]) + 1);
111+ mt76_apply_multi_array_limit(dest->path.ru_bf[0], ARRAY_SIZE(dest->path.ru_bf[0]),
112+ ARRAY_SIZE(dest->path.ru_bf), val, len,
developer70180b02023-11-14 17:01:47 +0800113+ target_power_combine, txs_delta);
developer327aa322023-07-10 13:49:56 +0800114
developer2cd12162024-04-18 17:29:00 +0800115 return max_power;
116 }
developera16be1f2022-12-14 13:09:20 +0800117diff --git a/mt76.h b/mt76.h
developer05f3b2b2024-08-19 19:17:34 +0800118index 253a564f..580320fd 100644
developera16be1f2022-12-14 13:09:20 +0800119--- a/mt76.h
120+++ b/mt76.h
developera46f6132024-03-26 14:09:54 +0800121@@ -1089,6 +1089,14 @@ struct mt76_power_limits {
developera16be1f2022-12-14 13:09:20 +0800122 s8 mcs[4][10];
123 s8 ru[7][12];
developerbd9fa1e2023-10-16 11:04:00 +0800124 s8 eht[16][16];
developera16be1f2022-12-14 13:09:20 +0800125+
126+ struct {
127+ s8 cck[4];
128+ s8 ofdm[4];
129+ s8 ofdm_bf[4];
130+ s8 ru[7][10];
131+ s8 ru_bf[7][10];
132+ } path;
133 };
134
135 struct mt76_ethtool_worker_info {
136diff --git a/mt7915/debugfs.c b/mt7915/debugfs.c
developer05f3b2b2024-08-19 19:17:34 +0800137index c3692969..3830a735 100644
developera16be1f2022-12-14 13:09:20 +0800138--- a/mt7915/debugfs.c
139+++ b/mt7915/debugfs.c
developerdc9eeae2024-04-08 14:36:46 +0800140@@ -1020,7 +1020,7 @@ mt7915_rate_txpower_get(struct file *file, char __user *user_buf,
developera16be1f2022-12-14 13:09:20 +0800141 if (!buf)
142 return -ENOMEM;
143
144- ret = mt7915_mcu_get_txpower_sku(phy, txpwr, sizeof(txpwr));
145+ ret = mt7915_mcu_get_txpower_sku(phy, txpwr, sizeof(txpwr), TX_POWER_INFO_RATE);
146 if (ret)
147 goto out;
148
developerdc9eeae2024-04-08 14:36:46 +0800149@@ -1134,7 +1134,7 @@ mt7915_rate_txpower_set(struct file *file, const char __user *user_buf,
developera16be1f2022-12-14 13:09:20 +0800150
151 mutex_lock(&dev->mt76.mutex);
152 ret = mt7915_mcu_get_txpower_sku(phy, req.txpower_sku,
153- sizeof(req.txpower_sku));
154+ sizeof(req.txpower_sku), TX_POWER_INFO_RATE);
155 if (ret)
156 goto out;
157
developerdc9eeae2024-04-08 14:36:46 +0800158@@ -1176,7 +1176,7 @@ out:
developera16be1f2022-12-14 13:09:20 +0800159 return ret ? ret : count;
160 }
161
162-static const struct file_operations mt7915_rate_txpower_fops = {
163+static const struct file_operations mt7915_txpower_fops = {
164 .write = mt7915_rate_txpower_set,
165 .read = mt7915_rate_txpower_get,
166 .open = simple_open,
developerdc9eeae2024-04-08 14:36:46 +0800167@@ -1184,6 +1184,69 @@ static const struct file_operations mt7915_rate_txpower_fops = {
developera16be1f2022-12-14 13:09:20 +0800168 .llseek = default_llseek,
169 };
170
171+static int
172+mt7915_path_txpower_show(struct seq_file *file)
173+{
174+ struct mt7915_phy *phy = file->private;
175+ s8 txpower[MT7915_SKU_PATH_NUM], *buf = txpower;
176+ int ret;
177+
178+#define PATH_POWER_SHOW(_name, _len, _skip) do { \
179+ if (_skip) { \
180+ buf -= 1; \
181+ *buf = 0; \
182+ } \
183+ mt76_seq_puts_array(file, _name, buf, _len); \
184+ buf += _len; \
185+ } while(0)
186+
developereb155692024-01-11 14:08:37 +0800187+ seq_printf(file, "\n%*c", 18, ' ');
developera16be1f2022-12-14 13:09:20 +0800188+ seq_printf(file, "1T1S/2T1S/3T1S/4T1S/2T2S/3T2S/4T2S/3T3S/4T3S/4T4S\n");
189+ ret = mt7915_mcu_get_txpower_sku(phy, txpower, sizeof(txpower),
190+ TX_POWER_INFO_PATH);
191+ if (ret)
192+ return ret;
193+
194+ PATH_POWER_SHOW("CCK", 4, 0);
195+ PATH_POWER_SHOW("OFDM", 4, 0);
196+ PATH_POWER_SHOW("BF-OFDM", 4, 1);
197+
developerf9b00212023-07-31 12:27:06 +0800198+ PATH_POWER_SHOW("HT/VHT20", 10, 0);
199+ PATH_POWER_SHOW("BF-HT/VHT20", 10, 1);
200+ PATH_POWER_SHOW("HT/VHT40", 10, 0);
201+ PATH_POWER_SHOW("BF-HT/VHT40", 10, 1);
developera16be1f2022-12-14 13:09:20 +0800202+
developerf9b00212023-07-31 12:27:06 +0800203+ PATH_POWER_SHOW("BW20/RU242", 10, 0);
204+ PATH_POWER_SHOW("BF-BW20/RU242", 10, 1);
205+ PATH_POWER_SHOW("BW40/RU484", 10, 0);
206+ PATH_POWER_SHOW("BF-BW40/RU484", 10, 1);
207+ PATH_POWER_SHOW("BW80/RU996", 10, 0);
208+ PATH_POWER_SHOW("BF-BW80/RU996", 10, 1);
209+ PATH_POWER_SHOW("BW160/RU2x996", 10, 0);
210+ PATH_POWER_SHOW("BF-BW160/RU2x996", 10, 1);
developera16be1f2022-12-14 13:09:20 +0800211+ PATH_POWER_SHOW("RU26", 10, 0);
212+ PATH_POWER_SHOW("BF-RU26", 10, 0);
213+ PATH_POWER_SHOW("RU52", 10, 0);
214+ PATH_POWER_SHOW("BF-RU52", 10, 0);
215+ PATH_POWER_SHOW("RU106", 10, 0);
216+ PATH_POWER_SHOW("BF-RU106", 10, 0);
217+#undef PATH_POWER_SHOW
218+
219+ return 0;
220+}
221+
222+static int
223+mt7915_txpower_path_show(struct seq_file *file, void *data)
224+{
225+ struct mt7915_phy *phy = file->private;
226+
227+ seq_printf(file, "\nBand %d\n", phy != &phy->dev->phy);
228+
229+ return mt7915_path_txpower_show(file);
230+}
231+
232+DEFINE_SHOW_ATTRIBUTE(mt7915_txpower_path);
233+
234 static int
235 mt7915_twt_stats(struct seq_file *s, void *data)
236 {
developer05f3b2b2024-08-19 19:17:34 +0800237@@ -1355,7 +1418,9 @@ int mt7915_init_debugfs(struct mt7915_phy *phy)
developera16be1f2022-12-14 13:09:20 +0800238 debugfs_create_file("implicit_txbf", 0600, dir, dev,
239 &fops_implicit_txbf);
240 debugfs_create_file("txpower_sku", 0400, dir, phy,
241- &mt7915_rate_txpower_fops);
242+ &mt7915_txpower_fops);
243+ debugfs_create_file("txpower_path", 0400, dir, phy,
244+ &mt7915_txpower_path_fops);
245 debugfs_create_devm_seqfile(dev->mt76.dev, "twt_stats", dir,
246 mt7915_twt_stats);
247 debugfs_create_file("rf_regval", 0600, dir, dev, &fops_rf_regval);
developer70180b02023-11-14 17:01:47 +0800248diff --git a/mt7915/init.c b/mt7915/init.c
developer05f3b2b2024-08-19 19:17:34 +0800249index 0c58ab7b..a9cb496b 100644
developer70180b02023-11-14 17:01:47 +0800250--- a/mt7915/init.c
251+++ b/mt7915/init.c
developer05f3b2b2024-08-19 19:17:34 +0800252@@ -285,6 +285,8 @@ static void __mt7915_init_txpower(struct mt7915_phy *phy,
developer70180b02023-11-14 17:01:47 +0800253 int pwr_delta = mt7915_eeprom_get_power_delta(dev, sband->band);
254 struct mt76_power_limits limits;
255
256+ phy->sku_limit_en = true;
257+ phy->sku_path_en = true;
258 for (i = 0; i < sband->n_channels; i++) {
259 struct ieee80211_channel *chan = &sband->channels[i];
260 u32 target_power = 0;
developer05f3b2b2024-08-19 19:17:34 +0800261@@ -301,6 +303,11 @@ static void __mt7915_init_txpower(struct mt7915_phy *phy,
developer70180b02023-11-14 17:01:47 +0800262 target_power = mt76_get_rate_power_limits(phy->mt76, chan,
263 &limits,
264 target_power);
265+
266+ /* MT7915N can not enable Backoff table without setting value in dts */
267+ if (!limits.path.ofdm[0])
268+ phy->sku_path_en = false;
269+
270 target_power += nss_delta;
271 target_power = DIV_ROUND_UP(target_power, 2);
272 chan->max_power = min_t(int, chan->max_reg_power,
273diff --git a/mt7915/main.c b/mt7915/main.c
developer05f3b2b2024-08-19 19:17:34 +0800274index de2f9098..4a5a0155 100644
developer70180b02023-11-14 17:01:47 +0800275--- a/mt7915/main.c
276+++ b/mt7915/main.c
developereb155692024-01-11 14:08:37 +0800277@@ -73,11 +73,7 @@ int mt7915_run(struct ieee80211_hw *hw)
278 if (ret)
developer70180b02023-11-14 17:01:47 +0800279 goto out;
280
developereb155692024-01-11 14:08:37 +0800281-#ifdef MTK_DEBUG
developer70180b02023-11-14 17:01:47 +0800282- ret = mt7915_mcu_set_sku_en(phy, !dev->dbg.sku_disable);
283-#else
284- ret = mt7915_mcu_set_sku_en(phy, true);
developereb155692024-01-11 14:08:37 +0800285-#endif
developer70180b02023-11-14 17:01:47 +0800286+ ret = mt7915_mcu_set_sku_en(phy);
287 if (ret)
288 goto out;
289
developera16be1f2022-12-14 13:09:20 +0800290diff --git a/mt7915/mcu.c b/mt7915/mcu.c
developer05f3b2b2024-08-19 19:17:34 +0800291index 85112791..1b5ef875 100644
developera16be1f2022-12-14 13:09:20 +0800292--- a/mt7915/mcu.c
293+++ b/mt7915/mcu.c
developera46f6132024-03-26 14:09:54 +0800294@@ -3422,7 +3422,8 @@ int mt7915_mcu_set_txpower_frame(struct mt7915_phy *phy,
developera16be1f2022-12-14 13:09:20 +0800295 int ret;
296 s8 txpower_sku[MT7915_SKU_RATE_NUM];
297
298- ret = mt7915_mcu_get_txpower_sku(phy, txpower_sku, sizeof(txpower_sku));
299+ ret = mt7915_mcu_get_txpower_sku(phy, txpower_sku, sizeof(txpower_sku),
300+ TX_POWER_INFO_RATE);
301 if (ret)
302 return ret;
303
developera46f6132024-03-26 14:09:54 +0800304@@ -3462,53 +3463,139 @@ int mt7915_mcu_set_txpower_frame(struct mt7915_phy *phy,
developer70180b02023-11-14 17:01:47 +0800305 sizeof(req), true);
306 }
developera16be1f2022-12-14 13:09:20 +0800307
developer70180b02023-11-14 17:01:47 +0800308+static void
309+mt7915_update_txpower(struct mt7915_phy *phy, int tx_power)
310+{
311+ struct mt76_phy *mphy = phy->mt76;
312+ struct ieee80211_channel *chan = mphy->main_chan;
313+ int chain_idx, val, e2p_power_limit = 0;
314+
315+ if (chan == NULL) {
316+ mphy->txpower_cur = tx_power;
317+ return;
318+ }
319+
320+ for (chain_idx = 0; chain_idx < hweight16(mphy->chainmask); chain_idx++) {
321+ val = mt7915_eeprom_get_target_power(phy->dev, chan, chain_idx);
322+ val += mt7915_eeprom_get_power_delta(phy->dev, chan->band);
323+
324+ e2p_power_limit = max_t(int, e2p_power_limit, val);
325+ }
326+
327+ if (phy->sku_limit_en)
328+ mphy->txpower_cur = min_t(int, e2p_power_limit, tx_power);
329+ else
330+ mphy->txpower_cur = e2p_power_limit;
331+}
332+
developera16be1f2022-12-14 13:09:20 +0800333 int mt7915_mcu_set_txpower_sku(struct mt7915_phy *phy)
334 {
335+#define TX_POWER_LIMIT_TABLE_RATE 0
336+#define TX_POWER_LIMIT_TABLE_PATH 1
337 struct mt7915_dev *dev = phy->dev;
338 struct mt76_phy *mphy = phy->mt76;
339 struct ieee80211_hw *hw = mphy->hw;
340- struct mt7915_mcu_txpower_sku req = {
341+ struct mt7915_sku_val {
342+ u8 format_id;
343+ u8 limit_type;
344+ u8 band_idx;
345+ } __packed hdr = {
346 .format_id = TX_POWER_LIMIT_TABLE,
347+ .limit_type = TX_POWER_LIMIT_TABLE_RATE,
348 .band_idx = phy->mt76->band_idx,
349 };
350- struct mt76_power_limits limits_array;
351- s8 *la = (s8 *)&limits_array;
352- int i, idx;
353- int tx_power;
354+ int i, ret, tx_power;
355+ const u8 *len = mt7915_sku_group_len;
356+ struct mt76_power_limits la = {};
357+ struct sk_buff *skb;
358
359 tx_power = mt7915_get_power_bound(phy, hw->conf.power_level);
developer70180b02023-11-14 17:01:47 +0800360- tx_power = mt76_get_rate_power_limits(mphy, mphy->chandef.chan,
developera16be1f2022-12-14 13:09:20 +0800361- &limits_array, tx_power);
developer70180b02023-11-14 17:01:47 +0800362- mphy->txpower_cur = tx_power;
developera16be1f2022-12-14 13:09:20 +0800363
364- for (i = 0, idx = 0; i < ARRAY_SIZE(mt7915_sku_group_len); i++) {
365- u8 mcs_num, len = mt7915_sku_group_len[i];
366- int j;
developer70180b02023-11-14 17:01:47 +0800367+ if (phy->sku_limit_en) {
368+ tx_power = mt76_get_rate_power_limits(mphy, mphy->chandef.chan,
369+ &la, tx_power);
370+ mt7915_update_txpower(phy, tx_power);
371+ } else {
372+ mt7915_update_txpower(phy, tx_power);
373+ return 0;
374+ }
375
376- if (i >= SKU_HT_BW20 && i <= SKU_VHT_BW160) {
377- mcs_num = 10;
developera16be1f2022-12-14 13:09:20 +0800378+ skb = mt76_mcu_msg_alloc(&dev->mt76, NULL,
379+ sizeof(hdr) + MT7915_SKU_RATE_NUM);
380+ if (!skb)
381+ return -ENOMEM;
382
developera16be1f2022-12-14 13:09:20 +0800383- if (i == SKU_HT_BW20 || i == SKU_VHT_BW20)
384- la = (s8 *)&limits_array + 12;
385- } else {
386- mcs_num = len;
387- }
developer70180b02023-11-14 17:01:47 +0800388+ skb_put_data(skb, &hdr, sizeof(hdr));
389+ skb_put_data(skb, &la.cck, len[SKU_CCK] + len[SKU_OFDM]);
390+ skb_put_data(skb, &la.mcs[0], len[SKU_HT_BW20]);
391+ skb_put_data(skb, &la.mcs[1], len[SKU_HT_BW40]);
392+
developera16be1f2022-12-14 13:09:20 +0800393+ /* vht */
394+ for (i = 0; i < 4; i++) {
395+ skb_put_data(skb, &la.mcs[i], sizeof(la.mcs[i]));
396+ skb_put_zero(skb, 2); /* padding */
397+ }
developerc5ce7502022-12-19 11:33:22 +0800398
developer327aa322023-07-10 13:49:56 +0800399- for (j = 0; j < min_t(u8, mcs_num, len); j++)
400- req.txpower_sku[idx + j] = la[j];
developereb155692024-01-11 14:08:37 +0800401+ /* he */
402+ skb_put_data(skb, &la.ru[0], sizeof(la.ru));
403
404- la += mcs_num;
405- idx += len;
developera16be1f2022-12-14 13:09:20 +0800406+ ret = mt76_mcu_skb_send_msg(&dev->mt76, skb,
407+ MCU_EXT_CMD(TX_POWER_FEATURE_CTRL), true);
408+ if (ret)
409+ return ret;
developereb155692024-01-11 14:08:37 +0800410+
developer70180b02023-11-14 17:01:47 +0800411+ /* only set per-path power table when it's configured */
412+ if (!phy->sku_path_en)
413+ return 0;
414+
developera16be1f2022-12-14 13:09:20 +0800415+ skb = mt76_mcu_msg_alloc(&dev->mt76, NULL,
416+ sizeof(hdr) + MT7915_SKU_PATH_NUM);
417+ if (!skb)
418+ return -ENOMEM;
developerc5ce7502022-12-19 11:33:22 +0800419+
developera16be1f2022-12-14 13:09:20 +0800420+ hdr.limit_type = TX_POWER_LIMIT_TABLE_PATH;
421+ skb_put_data(skb, &hdr, sizeof(hdr));
422+ skb_put_data(skb, &la.path.cck, sizeof(la.path.cck));
423+ skb_put_data(skb, &la.path.ofdm, sizeof(la.path.ofdm));
424+ skb_put_data(skb, &la.path.ofdm_bf[1], sizeof(la.path.ofdm_bf) - 1);
425+
426+ /* HT20 and HT40 */
developer327aa322023-07-10 13:49:56 +0800427+ skb_put_data(skb, &la.path.ru[3], sizeof(la.path.ru[3]));
428+ skb_put_data(skb, &la.path.ru_bf[3][1], sizeof(la.path.ru_bf[3]) - 1);
429+ skb_put_data(skb, &la.path.ru[4], sizeof(la.path.ru[4]));
430+ skb_put_data(skb, &la.path.ru_bf[4][1], sizeof(la.path.ru_bf[4]) - 1);
developera16be1f2022-12-14 13:09:20 +0800431+
432+ /* start from non-bf and bf fields of
433+ * BW20/RU242, BW40/RU484, BW80/RU996, BW160/RU2x996,
434+ * RU26, RU52, and RU106
435+ */
developera16be1f2022-12-14 13:09:20 +0800436+
developer327aa322023-07-10 13:49:56 +0800437+ for (i = 0; i < 8; i++) {
438+ bool bf = i % 2;
439+ u8 idx = (i + 6) / 2;
440+ s8 *buf = bf ? la.path.ru_bf[idx] : la.path.ru[idx];
developera16be1f2022-12-14 13:09:20 +0800441+ /* The non-bf fields of RU26 to RU106 are special cases */
developer327aa322023-07-10 13:49:56 +0800442+ if (bf)
developera16be1f2022-12-14 13:09:20 +0800443+ skb_put_data(skb, buf + 1, 9);
444+ else
445+ skb_put_data(skb, buf, 10);
446 }
447
448- return mt76_mcu_send_msg(&dev->mt76,
449- MCU_EXT_CMD(TX_POWER_FEATURE_CTRL), &req,
450- sizeof(req), true);
developer327aa322023-07-10 13:49:56 +0800451+ for (i = 0; i < 6; i++) {
452+ bool bf = i % 2;
453+ u8 idx = i / 2;
454+ s8 *buf = bf ? la.path.ru_bf[idx] : la.path.ru[idx];
455+
456+ skb_put_data(skb, buf, 10);
457+ }
458+
developera16be1f2022-12-14 13:09:20 +0800459+ return mt76_mcu_skb_send_msg(&dev->mt76, skb,
developerc5ce7502022-12-19 11:33:22 +0800460+ MCU_EXT_CMD(TX_POWER_FEATURE_CTRL), true);
developera16be1f2022-12-14 13:09:20 +0800461 }
462
463-int mt7915_mcu_get_txpower_sku(struct mt7915_phy *phy, s8 *txpower, int len)
464+int mt7915_mcu_get_txpower_sku(struct mt7915_phy *phy, s8 *txpower, int len,
465+ u8 category)
466 {
467-#define RATE_POWER_INFO 2
468 struct mt7915_dev *dev = phy->dev;
469 struct {
470 u8 format_id;
developera46f6132024-03-26 14:09:54 +0800471@@ -3517,10 +3604,9 @@ int mt7915_mcu_get_txpower_sku(struct mt7915_phy *phy, s8 *txpower, int len)
developera16be1f2022-12-14 13:09:20 +0800472 u8 _rsv;
473 } __packed req = {
474 .format_id = TX_POWER_LIMIT_INFO,
475- .category = RATE_POWER_INFO,
476+ .category = category,
477 .band_idx = phy->mt76->band_idx,
478 };
479- s8 txpower_sku[MT7915_SKU_RATE_NUM][2];
480 struct sk_buff *skb;
481 int ret, i;
482
developera46f6132024-03-26 14:09:54 +0800483@@ -3530,9 +3616,15 @@ int mt7915_mcu_get_txpower_sku(struct mt7915_phy *phy, s8 *txpower, int len)
developera16be1f2022-12-14 13:09:20 +0800484 if (ret)
485 return ret;
486
487- memcpy(txpower_sku, skb->data + 4, sizeof(txpower_sku));
488- for (i = 0; i < len; i++)
489- txpower[i] = txpower_sku[i][req.band_idx];
490+ if (category == TX_POWER_INFO_RATE) {
491+ s8 res[MT7915_SKU_RATE_NUM][2];
492+
493+ memcpy(res, skb->data + 4, sizeof(res));
494+ for (i = 0; i < len; i++)
495+ txpower[i] = res[i][req.band_idx];
496+ } else if (category == TX_POWER_INFO_PATH) {
497+ memcpy(txpower, skb->data + 4, len);
498+ }
499
500 dev_kfree_skb(skb);
501
developera46f6132024-03-26 14:09:54 +0800502@@ -3561,7 +3653,7 @@ int mt7915_mcu_set_test_param(struct mt7915_dev *dev, u8 param, bool test_mode,
developer70180b02023-11-14 17:01:47 +0800503 sizeof(req), false);
504 }
505
506-int mt7915_mcu_set_sku_en(struct mt7915_phy *phy, bool enable)
507+int mt7915_mcu_set_sku_en(struct mt7915_phy *phy)
508 {
509 struct mt7915_dev *dev = phy->dev;
510 struct mt7915_sku {
developera46f6132024-03-26 14:09:54 +0800511@@ -3572,10 +3664,24 @@ int mt7915_mcu_set_sku_en(struct mt7915_phy *phy, bool enable)
developer70180b02023-11-14 17:01:47 +0800512 } __packed req = {
513 .format_id = TX_POWER_LIMIT_ENABLE,
developera16be1f2022-12-14 13:09:20 +0800514 .band_idx = phy->mt76->band_idx,
developer70180b02023-11-14 17:01:47 +0800515- .sku_enable = enable,
developera16be1f2022-12-14 13:09:20 +0800516 };
developereb155692024-01-11 14:08:37 +0800517+ int ret, sku_disable = 0;
developera16be1f2022-12-14 13:09:20 +0800518+
developereb155692024-01-11 14:08:37 +0800519+#ifdef MTK_DEBUG
520+ sku_disable = dev->dbg.sku_disable;
521+#endif
522+ req.sku_enable = sku_disable ? 0 : phy->sku_limit_en;
developera16be1f2022-12-14 13:09:20 +0800523+ ret = mt76_mcu_send_msg(&dev->mt76,
524+ MCU_EXT_CMD(TX_POWER_FEATURE_CTRL), &req,
525+ sizeof(req), true);
526+ if (ret)
527+ return ret;
developer70180b02023-11-14 17:01:47 +0800528+
529+ pr_info("%s: sku enable = %d, path enable = %d\n", __func__,
developereb155692024-01-11 14:08:37 +0800530+ sku_disable ? 0 : phy->sku_limit_en, sku_disable ? 0 : phy->sku_path_en);
developera16be1f2022-12-14 13:09:20 +0800531
developer70180b02023-11-14 17:01:47 +0800532- pr_info("%s: enable = %d\n", __func__, enable);
developereb155692024-01-11 14:08:37 +0800533+ req.sku_enable = sku_disable ? 0 : phy->sku_path_en;
developera16be1f2022-12-14 13:09:20 +0800534+ req.format_id = TX_POWER_LIMIT_PATH_ENABLE;
developer70180b02023-11-14 17:01:47 +0800535
developera16be1f2022-12-14 13:09:20 +0800536 return mt76_mcu_send_msg(&dev->mt76,
537 MCU_EXT_CMD(TX_POWER_FEATURE_CTRL), &req,
developera16be1f2022-12-14 13:09:20 +0800538diff --git a/mt7915/mcu.h b/mt7915/mcu.h
developer05f3b2b2024-08-19 19:17:34 +0800539index 1b0bd06b..94eff268 100644
developera16be1f2022-12-14 13:09:20 +0800540--- a/mt7915/mcu.h
541+++ b/mt7915/mcu.h
developer753619c2024-02-22 13:42:45 +0800542@@ -517,12 +517,18 @@ enum {
developera16be1f2022-12-14 13:09:20 +0800543
544 enum {
545 TX_POWER_LIMIT_ENABLE,
546+ TX_POWER_LIMIT_PATH_ENABLE = 0x3,
547 TX_POWER_LIMIT_TABLE = 0x4,
548 TX_POWER_LIMIT_INFO = 0x7,
549 TX_POWER_LIMIT_FRAME = 0x11,
550 TX_POWER_LIMIT_FRAME_MIN = 0x12,
551 };
552
553+enum {
554+ TX_POWER_INFO_PATH = 1,
555+ TX_POWER_INFO_RATE,
556+};
557+
558 enum {
559 SPR_ENABLE = 0x1,
560 SPR_ENABLE_SD = 0x3,
561diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
developer05f3b2b2024-08-19 19:17:34 +0800562index 7d068e1e..437cfb63 100644
developera16be1f2022-12-14 13:09:20 +0800563--- a/mt7915/mt7915.h
564+++ b/mt7915/mt7915.h
developer7af0f762023-05-22 15:16:16 +0800565@@ -72,6 +72,7 @@
developera16be1f2022-12-14 13:09:20 +0800566 #define MT7915_CDEV_THROTTLE_MAX 99
567
568 #define MT7915_SKU_RATE_NUM 161
569+#define MT7915_SKU_PATH_NUM 185
570
571 #define MT7915_MAX_TWT_AGRT 16
572 #define MT7915_MAX_STA_TWT_AGRT 8
developer05f3b2b2024-08-19 19:17:34 +0800573@@ -313,6 +314,9 @@ struct mt7915_phy {
developer70180b02023-11-14 17:01:47 +0800574 struct list_head stats_list;
575 spinlock_t stats_lock;
576
577+ bool sku_limit_en;
578+ bool sku_path_en;
579+
580 #ifdef CONFIG_NL80211_TESTMODE
581 struct {
582 u32 *reg_backup;
developer05f3b2b2024-08-19 19:17:34 +0800583@@ -643,9 +647,10 @@ int mt7915_mcu_set_mac(struct mt7915_dev *dev, int band, bool enable,
developer70180b02023-11-14 17:01:47 +0800584 int mt7915_mcu_set_test_param(struct mt7915_dev *dev, u8 param, bool test_mode,
585 u8 en);
developera16be1f2022-12-14 13:09:20 +0800586 int mt7915_mcu_set_ser(struct mt7915_dev *dev, u8 action, u8 set, u8 band);
developer70180b02023-11-14 17:01:47 +0800587-int mt7915_mcu_set_sku_en(struct mt7915_phy *phy, bool enable);
588+int mt7915_mcu_set_sku_en(struct mt7915_phy *phy);
developera16be1f2022-12-14 13:09:20 +0800589 int mt7915_mcu_set_txpower_sku(struct mt7915_phy *phy);
590-int mt7915_mcu_get_txpower_sku(struct mt7915_phy *phy, s8 *txpower, int len);
591+int mt7915_mcu_get_txpower_sku(struct mt7915_phy *phy, s8 *txpower, int len,
592+ u8 category);
593 int mt7915_mcu_set_txpower_frame_min(struct mt7915_phy *phy, s8 txpower);
594 int mt7915_mcu_set_txpower_frame(struct mt7915_phy *phy,
595 struct ieee80211_vif *vif,
596--
developerbd9fa1e2023-10-16 11:04:00 +08005972.18.0
developera16be1f2022-12-14 13:09:20 +0800598