blob: 09c90be8b4022ab9612724d27be6b81a0ac1035d [file] [log] [blame]
developer12a42792023-07-29 05:30:55 +08001From d8e0738120aa767d990e2879b944716242b0f38d Mon Sep 17 00:00:00 2001
developerfe7be7f2022-12-13 21:40:24 +08002From: Shayne Chen <shayne.chen@mediatek.com>
3Date: Mon, 5 Dec 2022 18:21:51 +0800
developer8f0d89b2023-07-28 07:16:44 +08004Subject: [PATCH 1025/1034] wifi: mt76: mt7915: add bf backoff limit table
developerc9233442023-04-04 06:06:17 +08005 support
developerfe7be7f2022-12-13 21:40:24 +08006
7Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
8---
developer2594fb72023-07-20 14:56:49 +08009 debugfs.c | 2 +-
developer12a42792023-07-29 05:30:55 +080010 eeprom.c | 34 +++++++++++-
developerfe7be7f2022-12-13 21:40:24 +080011 mt76.h | 8 +++
developer12a42792023-07-29 05:30:55 +080012 mt7915/debugfs.c | 73 ++++++++++++++++++++++++--
13 mt7915/main.c | 2 +-
developerf520c8d2023-06-19 10:33:45 +080014 mt7915/mcu.c | 132 ++++++++++++++++++++++++++++++++++++-----------
developer12a42792023-07-29 05:30:55 +080015 mt7915/mcu.h | 6 +++
developerfe7be7f2022-12-13 21:40:24 +080016 mt7915/mt7915.h | 4 +-
developer12a42792023-07-29 05:30:55 +080017 8 files changed, 221 insertions(+), 40 deletions(-)
developerfe7be7f2022-12-13 21:40:24 +080018
developer2594fb72023-07-20 14:56:49 +080019diff --git a/debugfs.c b/debugfs.c
20index 4a8e186..4bb4679 100644
21--- a/debugfs.c
22+++ b/debugfs.c
23@@ -95,7 +95,7 @@ void mt76_seq_puts_array(struct seq_file *file, const char *str,
24 {
25 int i;
26
27- seq_printf(file, "%10s:", str);
28+ seq_printf(file, "%16s:", str);
29 for (i = 0; i < len; i++)
30 seq_printf(file, " %2d", val[i]);
31 seq_puts(file, "\n");
developerfe7be7f2022-12-13 21:40:24 +080032diff --git a/eeprom.c b/eeprom.c
developer12a42792023-07-29 05:30:55 +080033index 6b72774..5cbd56f 100644
developerfe7be7f2022-12-13 21:40:24 +080034--- a/eeprom.c
35+++ b/eeprom.c
developer12a42792023-07-29 05:30:55 +080036@@ -312,12 +312,16 @@ s8 mt76_get_rate_power_limits(struct mt76_phy *phy,
developerf520c8d2023-06-19 10:33:45 +080037 char band;
38 size_t len;
developer12a42792023-07-29 05:30:55 +080039 s8 max_power = -127;
developerf520c8d2023-06-19 10:33:45 +080040+ s8 max_power_backoff = -127;
41 s8 txs_delta;
developer2594fb72023-07-20 14:56:49 +080042+ int n_chains = hweight16(phy->chainmask);
developerf520c8d2023-06-19 10:33:45 +080043+ s8 target_power_combine = target_power + mt76_tx_power_nss_delta(n_chains);
44
developerfe7be7f2022-12-13 21:40:24 +080045 if (!mcs_rates)
46 mcs_rates = 10;
47
48- memset(dest, target_power, sizeof(*dest));
49+ memset(dest, target_power, sizeof(*dest) - sizeof(dest->path));
50+ memset(&dest->path, 0, sizeof(dest->path));
51
52 if (!IS_ENABLED(CONFIG_OF))
53 return target_power;
developerf520c8d2023-06-19 10:33:45 +080054@@ -370,7 +374,33 @@ s8 mt76_get_rate_power_limits(struct mt76_phy *phy,
developerfe7be7f2022-12-13 21:40:24 +080055 ARRAY_SIZE(dest->ru), val, len,
56 target_power, txs_delta, &max_power);
57
developerf520c8d2023-06-19 10:33:45 +080058- return max_power;
59+ max_power_backoff = max_power;
developerfe7be7f2022-12-13 21:40:24 +080060+ val = mt76_get_of_array(np, "paths-cck", &len, ARRAY_SIZE(dest->path.cck));
61+ mt76_apply_array_limit(dest->path.cck, ARRAY_SIZE(dest->path.cck), val,
developerf520c8d2023-06-19 10:33:45 +080062+ target_power_combine, txs_delta, &max_power_backoff);
developerfe7be7f2022-12-13 21:40:24 +080063+
64+ val = mt76_get_of_array(np, "paths-ofdm", &len, ARRAY_SIZE(dest->path.ofdm));
65+ mt76_apply_array_limit(dest->path.ofdm, ARRAY_SIZE(dest->path.ofdm), val,
developerf520c8d2023-06-19 10:33:45 +080066+ target_power_combine, txs_delta, &max_power_backoff);
developerfe7be7f2022-12-13 21:40:24 +080067+
68+ val = mt76_get_of_array(np, "paths-ofdm-bf", &len, ARRAY_SIZE(dest->path.ofdm_bf));
69+ mt76_apply_array_limit(dest->path.ofdm_bf, ARRAY_SIZE(dest->path.ofdm_bf), val,
developerf520c8d2023-06-19 10:33:45 +080070+ target_power_combine, txs_delta, &max_power_backoff);
developerfe7be7f2022-12-13 21:40:24 +080071+
72+ val = mt76_get_of_array(np, "paths-ru", &len, ARRAY_SIZE(dest->path.ru[0]) + 1);
73+ mt76_apply_multi_array_limit(dest->path.ru[0], ARRAY_SIZE(dest->path.ru[0]),
74+ ARRAY_SIZE(dest->path.ru), val, len,
developerf520c8d2023-06-19 10:33:45 +080075+ target_power_combine, txs_delta, &max_power_backoff);
developerfe7be7f2022-12-13 21:40:24 +080076+
77+ val = mt76_get_of_array(np, "paths-ru-bf", &len, ARRAY_SIZE(dest->path.ru_bf[0]) + 1);
78+ mt76_apply_multi_array_limit(dest->path.ru_bf[0], ARRAY_SIZE(dest->path.ru_bf[0]),
79+ ARRAY_SIZE(dest->path.ru_bf), val, len,
developerf520c8d2023-06-19 10:33:45 +080080+ target_power_combine, txs_delta, &max_power_backoff);
developerfe7be7f2022-12-13 21:40:24 +080081+
developerf520c8d2023-06-19 10:33:45 +080082+ if (max_power_backoff == target_power_combine)
83+ return max_power;
84+
85+ return max_power_backoff;
developerfe7be7f2022-12-13 21:40:24 +080086 }
87 EXPORT_SYMBOL_GPL(mt76_get_rate_power_limits);
developerf520c8d2023-06-19 10:33:45 +080088
developerfe7be7f2022-12-13 21:40:24 +080089diff --git a/mt76.h b/mt76.h
developer2157bf82023-06-26 02:27:49 +080090index b4e3429..2f801de 100644
developerfe7be7f2022-12-13 21:40:24 +080091--- a/mt76.h
92+++ b/mt76.h
developer2157bf82023-06-26 02:27:49 +080093@@ -1030,6 +1030,14 @@ struct mt76_power_limits {
developerfe7be7f2022-12-13 21:40:24 +080094 s8 ofdm[8];
95 s8 mcs[4][10];
96 s8 ru[7][12];
97+
98+ struct {
99+ s8 cck[4];
100+ s8 ofdm[4];
101+ s8 ofdm_bf[4];
102+ s8 ru[7][10];
103+ s8 ru_bf[7][10];
104+ } path;
105 };
106
107 struct mt76_ethtool_worker_info {
108diff --git a/mt7915/debugfs.c b/mt7915/debugfs.c
developer12a42792023-07-29 05:30:55 +0800109index f181377..19a37b5 100644
developerfe7be7f2022-12-13 21:40:24 +0800110--- a/mt7915/debugfs.c
111+++ b/mt7915/debugfs.c
developer2157bf82023-06-26 02:27:49 +0800112@@ -1019,7 +1019,7 @@ mt7915_rate_txpower_get(struct file *file, char __user *user_buf,
developerfe7be7f2022-12-13 21:40:24 +0800113 if (!buf)
114 return -ENOMEM;
115
116- ret = mt7915_mcu_get_txpower_sku(phy, txpwr, sizeof(txpwr));
117+ ret = mt7915_mcu_get_txpower_sku(phy, txpwr, sizeof(txpwr), TX_POWER_INFO_RATE);
118 if (ret)
119 goto out;
120
developer12a42792023-07-29 05:30:55 +0800121@@ -1133,7 +1133,7 @@ mt7915_rate_txpower_set(struct file *file, const char __user *user_buf,
developerfe7be7f2022-12-13 21:40:24 +0800122
123 mutex_lock(&dev->mt76.mutex);
124 ret = mt7915_mcu_get_txpower_sku(phy, req.txpower_sku,
125- sizeof(req.txpower_sku));
126+ sizeof(req.txpower_sku), TX_POWER_INFO_RATE);
127 if (ret)
128 goto out;
129
developer12a42792023-07-29 05:30:55 +0800130@@ -1175,7 +1175,7 @@ out:
developerfe7be7f2022-12-13 21:40:24 +0800131 return ret ? ret : count;
132 }
133
134-static const struct file_operations mt7915_rate_txpower_fops = {
135+static const struct file_operations mt7915_txpower_fops = {
136 .write = mt7915_rate_txpower_set,
137 .read = mt7915_rate_txpower_get,
138 .open = simple_open,
developer12a42792023-07-29 05:30:55 +0800139@@ -1183,6 +1183,69 @@ static const struct file_operations mt7915_rate_txpower_fops = {
developerfe7be7f2022-12-13 21:40:24 +0800140 .llseek = default_llseek,
141 };
142
143+static int
144+mt7915_path_txpower_show(struct seq_file *file)
145+{
146+ struct mt7915_phy *phy = file->private;
147+ s8 txpower[MT7915_SKU_PATH_NUM], *buf = txpower;
148+ int ret;
149+
150+#define PATH_POWER_SHOW(_name, _len, _skip) do { \
151+ if (_skip) { \
152+ buf -= 1; \
153+ *buf = 0; \
154+ } \
155+ mt76_seq_puts_array(file, _name, buf, _len); \
156+ buf += _len; \
157+ } while(0)
158+
developer2594fb72023-07-20 14:56:49 +0800159+ seq_printf(file, "\n%*c", 17, ' ');
developerfe7be7f2022-12-13 21:40:24 +0800160+ seq_printf(file, "1T1S/2T1S/3T1S/4T1S/2T2S/3T2S/4T2S/3T3S/4T3S/4T4S\n");
161+ ret = mt7915_mcu_get_txpower_sku(phy, txpower, sizeof(txpower),
162+ TX_POWER_INFO_PATH);
163+ if (ret)
164+ return ret;
165+
166+ PATH_POWER_SHOW("CCK", 4, 0);
167+ PATH_POWER_SHOW("OFDM", 4, 0);
168+ PATH_POWER_SHOW("BF-OFDM", 4, 1);
169+
developer2594fb72023-07-20 14:56:49 +0800170+ PATH_POWER_SHOW("HT/VHT20", 10, 0);
171+ PATH_POWER_SHOW("BF-HT/VHT20", 10, 1);
172+ PATH_POWER_SHOW("HT/VHT40", 10, 0);
173+ PATH_POWER_SHOW("BF-HT/VHT40", 10, 1);
developerfe7be7f2022-12-13 21:40:24 +0800174+
developer2594fb72023-07-20 14:56:49 +0800175+ PATH_POWER_SHOW("BW20/RU242", 10, 0);
176+ PATH_POWER_SHOW("BF-BW20/RU242", 10, 1);
177+ PATH_POWER_SHOW("BW40/RU484", 10, 0);
178+ PATH_POWER_SHOW("BF-BW40/RU484", 10, 1);
179+ PATH_POWER_SHOW("BW80/RU996", 10, 0);
180+ PATH_POWER_SHOW("BF-BW80/RU996", 10, 1);
181+ PATH_POWER_SHOW("BW160/RU2x996", 10, 0);
182+ PATH_POWER_SHOW("BF-BW160/RU2x996", 10, 1);
developerfe7be7f2022-12-13 21:40:24 +0800183+ PATH_POWER_SHOW("RU26", 10, 0);
184+ PATH_POWER_SHOW("BF-RU26", 10, 0);
185+ PATH_POWER_SHOW("RU52", 10, 0);
186+ PATH_POWER_SHOW("BF-RU52", 10, 0);
187+ PATH_POWER_SHOW("RU106", 10, 0);
188+ PATH_POWER_SHOW("BF-RU106", 10, 0);
189+#undef PATH_POWER_SHOW
190+
191+ return 0;
192+}
193+
194+static int
195+mt7915_txpower_path_show(struct seq_file *file, void *data)
196+{
197+ struct mt7915_phy *phy = file->private;
198+
199+ seq_printf(file, "\nBand %d\n", phy != &phy->dev->phy);
200+
201+ return mt7915_path_txpower_show(file);
202+}
203+
204+DEFINE_SHOW_ATTRIBUTE(mt7915_txpower_path);
205+
206 static int
207 mt7915_twt_stats(struct seq_file *s, void *data)
208 {
developer12a42792023-07-29 05:30:55 +0800209@@ -1269,7 +1332,9 @@ int mt7915_init_debugfs(struct mt7915_phy *phy)
developerfe7be7f2022-12-13 21:40:24 +0800210 debugfs_create_file("implicit_txbf", 0600, dir, dev,
211 &fops_implicit_txbf);
212 debugfs_create_file("txpower_sku", 0400, dir, phy,
213- &mt7915_rate_txpower_fops);
214+ &mt7915_txpower_fops);
215+ debugfs_create_file("txpower_path", 0400, dir, phy,
216+ &mt7915_txpower_path_fops);
217 debugfs_create_devm_seqfile(dev->mt76.dev, "twt_stats", dir,
218 mt7915_twt_stats);
219 debugfs_create_file("rf_regval", 0600, dir, dev, &fops_rf_regval);
developerf520c8d2023-06-19 10:33:45 +0800220diff --git a/mt7915/main.c b/mt7915/main.c
developer12a42792023-07-29 05:30:55 +0800221index dc6ef88..bd2c1cf 100644
developerf520c8d2023-06-19 10:33:45 +0800222--- a/mt7915/main.c
223+++ b/mt7915/main.c
developer2594fb72023-07-20 14:56:49 +0800224@@ -488,7 +488,7 @@ static int mt7915_config(struct ieee80211_hw *hw, u32 changed)
225 ieee80211_wake_queues(hw);
226 }
227
228- if (changed & IEEE80211_CONF_CHANGE_POWER) {
229+ if (changed & (IEEE80211_CONF_CHANGE_POWER | IEEE80211_CONF_CHANGE_CHANNEL)) {
230 ret = mt7915_mcu_set_txpower_sku(phy);
231 if (ret)
232 return ret;
developerfe7be7f2022-12-13 21:40:24 +0800233diff --git a/mt7915/mcu.c b/mt7915/mcu.c
developer8f0d89b2023-07-28 07:16:44 +0800234index 4aee126..10fade2 100644
developerfe7be7f2022-12-13 21:40:24 +0800235--- a/mt7915/mcu.c
236+++ b/mt7915/mcu.c
developer2594fb72023-07-20 14:56:49 +0800237@@ -3302,7 +3302,8 @@ int mt7915_mcu_set_txpower_frame(struct mt7915_phy *phy,
developerfe7be7f2022-12-13 21:40:24 +0800238 int ret;
239 s8 txpower_sku[MT7915_SKU_RATE_NUM];
240
241- ret = mt7915_mcu_get_txpower_sku(phy, txpower_sku, sizeof(txpower_sku));
242+ ret = mt7915_mcu_get_txpower_sku(phy, txpower_sku, sizeof(txpower_sku),
243+ TX_POWER_INFO_RATE);
244 if (ret)
245 return ret;
246
developer2594fb72023-07-20 14:56:49 +0800247@@ -3344,51 +3345,106 @@ int mt7915_mcu_set_txpower_frame(struct mt7915_phy *phy,
developerfe7be7f2022-12-13 21:40:24 +0800248
249 int mt7915_mcu_set_txpower_sku(struct mt7915_phy *phy)
250 {
251+#define TX_POWER_LIMIT_TABLE_RATE 0
252+#define TX_POWER_LIMIT_TABLE_PATH 1
253 struct mt7915_dev *dev = phy->dev;
254 struct mt76_phy *mphy = phy->mt76;
255 struct ieee80211_hw *hw = mphy->hw;
256- struct mt7915_mcu_txpower_sku req = {
257+ struct mt7915_sku_val {
258+ u8 format_id;
259+ u8 limit_type;
260+ u8 band_idx;
261+ } __packed hdr = {
262 .format_id = TX_POWER_LIMIT_TABLE,
263+ .limit_type = TX_POWER_LIMIT_TABLE_RATE,
264 .band_idx = phy->mt76->band_idx,
265 };
266- struct mt76_power_limits limits_array;
267- s8 *la = (s8 *)&limits_array;
268- int i, idx;
269- int tx_power;
270+ int i, ret, tx_power;
271+ const u8 *len = mt7915_sku_group_len;
272+ struct mt76_power_limits la = {};
273+ struct sk_buff *skb;
274
275 tx_power = mt7915_get_power_bound(phy, hw->conf.power_level);
276 tx_power = mt76_get_rate_power_limits(mphy, mphy->chandef.chan,
277- &limits_array, tx_power);
278+ &la, tx_power);
279 mphy->txpower_cur = tx_power;
280
281- for (i = 0, idx = 0; i < ARRAY_SIZE(mt7915_sku_group_len); i++) {
282- u8 mcs_num, len = mt7915_sku_group_len[i];
283- int j;
284+ skb = mt76_mcu_msg_alloc(&dev->mt76, NULL,
285+ sizeof(hdr) + MT7915_SKU_RATE_NUM);
286+ if (!skb)
287+ return -ENOMEM;
288
289- if (i >= SKU_HT_BW20 && i <= SKU_VHT_BW160) {
290- mcs_num = 10;
291+ skb_put_data(skb, &hdr, sizeof(hdr));
292+ skb_put_data(skb, &la.cck, len[SKU_CCK] + len[SKU_OFDM]);
293+ skb_put_data(skb, &la.mcs[0], len[SKU_HT_BW20]);
294+ skb_put_data(skb, &la.mcs[1], len[SKU_HT_BW40]);
295
296- if (i == SKU_HT_BW20 || i == SKU_VHT_BW20)
297- la = (s8 *)&limits_array + 12;
298- } else {
299- mcs_num = len;
300- }
301+ /* vht */
302+ for (i = 0; i < 4; i++) {
303+ skb_put_data(skb, &la.mcs[i], sizeof(la.mcs[i]));
304+ skb_put_zero(skb, 2); /* padding */
305+ }
developerf520c8d2023-06-19 10:33:45 +0800306+
developerfe7be7f2022-12-13 21:40:24 +0800307+ /* he */
308+ skb_put_data(skb, &la.ru[0], sizeof(la.ru));
developer30d39c22022-12-16 10:29:49 +0800309
developerf520c8d2023-06-19 10:33:45 +0800310- for (j = 0; j < min_t(u8, mcs_num, len); j++)
311- req.txpower_sku[idx + j] = la[j];
developerfe7be7f2022-12-13 21:40:24 +0800312+ ret = mt76_mcu_skb_send_msg(&dev->mt76, skb,
313+ MCU_EXT_CMD(TX_POWER_FEATURE_CTRL), true);
314+ if (ret)
315+ return ret;
316+
317+ /* only set per-path power table when it's configured */
318+ if (!la.path.ofdm[0])
319+ return 0;
developerf520c8d2023-06-19 10:33:45 +0800320
321- la += mcs_num;
322- idx += len;
developerfe7be7f2022-12-13 21:40:24 +0800323+ skb = mt76_mcu_msg_alloc(&dev->mt76, NULL,
324+ sizeof(hdr) + MT7915_SKU_PATH_NUM);
325+ if (!skb)
326+ return -ENOMEM;
developer30d39c22022-12-16 10:29:49 +0800327+
developerfe7be7f2022-12-13 21:40:24 +0800328+ hdr.limit_type = TX_POWER_LIMIT_TABLE_PATH;
329+ skb_put_data(skb, &hdr, sizeof(hdr));
330+ skb_put_data(skb, &la.path.cck, sizeof(la.path.cck));
331+ skb_put_data(skb, &la.path.ofdm, sizeof(la.path.ofdm));
332+ skb_put_data(skb, &la.path.ofdm_bf[1], sizeof(la.path.ofdm_bf) - 1);
333+
334+ /* HT20 and HT40 */
developerf520c8d2023-06-19 10:33:45 +0800335+ skb_put_data(skb, &la.path.ru[3], sizeof(la.path.ru[3]));
336+ skb_put_data(skb, &la.path.ru_bf[3][1], sizeof(la.path.ru_bf[3]) - 1);
337+ skb_put_data(skb, &la.path.ru[4], sizeof(la.path.ru[4]));
338+ skb_put_data(skb, &la.path.ru_bf[4][1], sizeof(la.path.ru_bf[4]) - 1);
developerfe7be7f2022-12-13 21:40:24 +0800339+
340+ /* start from non-bf and bf fields of
341+ * BW20/RU242, BW40/RU484, BW80/RU996, BW160/RU2x996,
342+ * RU26, RU52, and RU106
343+ */
developerfe7be7f2022-12-13 21:40:24 +0800344+
developerf520c8d2023-06-19 10:33:45 +0800345+ for (i = 0; i < 8; i++) {
346+ bool bf = i % 2;
347+ u8 idx = (i + 6) / 2;
348+ s8 *buf = bf ? la.path.ru_bf[idx] : la.path.ru[idx];
developerfe7be7f2022-12-13 21:40:24 +0800349+ /* The non-bf fields of RU26 to RU106 are special cases */
developerf520c8d2023-06-19 10:33:45 +0800350+ if (bf)
developerfe7be7f2022-12-13 21:40:24 +0800351+ skb_put_data(skb, buf + 1, 9);
352+ else
353+ skb_put_data(skb, buf, 10);
354 }
355
356- return mt76_mcu_send_msg(&dev->mt76,
357- MCU_EXT_CMD(TX_POWER_FEATURE_CTRL), &req,
358- sizeof(req), true);
developerf520c8d2023-06-19 10:33:45 +0800359+ for (i = 0; i < 6; i++) {
360+ bool bf = i % 2;
361+ u8 idx = i / 2;
362+ s8 *buf = bf ? la.path.ru_bf[idx] : la.path.ru[idx];
363+
364+ skb_put_data(skb, buf, 10);
365+ }
366+
developerfe7be7f2022-12-13 21:40:24 +0800367+ return mt76_mcu_skb_send_msg(&dev->mt76, skb,
developer30d39c22022-12-16 10:29:49 +0800368+ MCU_EXT_CMD(TX_POWER_FEATURE_CTRL), true);
developerfe7be7f2022-12-13 21:40:24 +0800369 }
370
371-int mt7915_mcu_get_txpower_sku(struct mt7915_phy *phy, s8 *txpower, int len)
372+int mt7915_mcu_get_txpower_sku(struct mt7915_phy *phy, s8 *txpower, int len,
373+ u8 category)
374 {
375-#define RATE_POWER_INFO 2
376 struct mt7915_dev *dev = phy->dev;
377 struct {
378 u8 format_id;
developer2594fb72023-07-20 14:56:49 +0800379@@ -3397,10 +3453,9 @@ int mt7915_mcu_get_txpower_sku(struct mt7915_phy *phy, s8 *txpower, int len)
developerfe7be7f2022-12-13 21:40:24 +0800380 u8 _rsv;
381 } __packed req = {
382 .format_id = TX_POWER_LIMIT_INFO,
383- .category = RATE_POWER_INFO,
384+ .category = category,
385 .band_idx = phy->mt76->band_idx,
386 };
387- s8 txpower_sku[MT7915_SKU_RATE_NUM][2];
388 struct sk_buff *skb;
389 int ret, i;
390
developer2594fb72023-07-20 14:56:49 +0800391@@ -3410,9 +3465,15 @@ int mt7915_mcu_get_txpower_sku(struct mt7915_phy *phy, s8 *txpower, int len)
developerfe7be7f2022-12-13 21:40:24 +0800392 if (ret)
393 return ret;
394
395- memcpy(txpower_sku, skb->data + 4, sizeof(txpower_sku));
396- for (i = 0; i < len; i++)
397- txpower[i] = txpower_sku[i][req.band_idx];
398+ if (category == TX_POWER_INFO_RATE) {
399+ s8 res[MT7915_SKU_RATE_NUM][2];
400+
401+ memcpy(res, skb->data + 4, sizeof(res));
402+ for (i = 0; i < len; i++)
403+ txpower[i] = res[i][req.band_idx];
404+ } else if (category == TX_POWER_INFO_PATH) {
405+ memcpy(txpower, skb->data + 4, len);
406+ }
407
408 dev_kfree_skb(skb);
409
developer2594fb72023-07-20 14:56:49 +0800410@@ -3454,9 +3515,18 @@ int mt7915_mcu_set_sku_en(struct mt7915_phy *phy, bool enable)
developerfe7be7f2022-12-13 21:40:24 +0800411 .band_idx = phy->mt76->band_idx,
412 .sku_enable = enable,
413 };
414+ int ret;
415+
416+ ret = mt76_mcu_send_msg(&dev->mt76,
417+ MCU_EXT_CMD(TX_POWER_FEATURE_CTRL), &req,
418+ sizeof(req), true);
419+ if (ret)
420+ return ret;
421
422 pr_info("%s: enable = %d\n", __func__, enable);
423
424+ req.format_id = TX_POWER_LIMIT_PATH_ENABLE;
developer30d39c22022-12-16 10:29:49 +0800425+
developerfe7be7f2022-12-13 21:40:24 +0800426 return mt76_mcu_send_msg(&dev->mt76,
427 MCU_EXT_CMD(TX_POWER_FEATURE_CTRL), &req,
428 sizeof(req), true);
429diff --git a/mt7915/mcu.h b/mt7915/mcu.h
developer12a42792023-07-29 05:30:55 +0800430index 5fc4e2e..142bfc1 100644
developerfe7be7f2022-12-13 21:40:24 +0800431--- a/mt7915/mcu.h
432+++ b/mt7915/mcu.h
developerbbd45e12023-05-19 08:22:06 +0800433@@ -502,12 +502,18 @@ enum {
developerfe7be7f2022-12-13 21:40:24 +0800434
435 enum {
436 TX_POWER_LIMIT_ENABLE,
437+ TX_POWER_LIMIT_PATH_ENABLE = 0x3,
438 TX_POWER_LIMIT_TABLE = 0x4,
439 TX_POWER_LIMIT_INFO = 0x7,
440 TX_POWER_LIMIT_FRAME = 0x11,
441 TX_POWER_LIMIT_FRAME_MIN = 0x12,
442 };
443
444+enum {
445+ TX_POWER_INFO_PATH = 1,
446+ TX_POWER_INFO_RATE,
447+};
448+
449 enum {
450 SPR_ENABLE = 0x1,
451 SPR_ENABLE_SD = 0x3,
452diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
developerf520c8d2023-06-19 10:33:45 +0800453index bbcdd93..b80c607 100644
developerfe7be7f2022-12-13 21:40:24 +0800454--- a/mt7915/mt7915.h
455+++ b/mt7915/mt7915.h
developerbbd45e12023-05-19 08:22:06 +0800456@@ -72,6 +72,7 @@
developerfe7be7f2022-12-13 21:40:24 +0800457 #define MT7915_CDEV_THROTTLE_MAX 99
458
459 #define MT7915_SKU_RATE_NUM 161
460+#define MT7915_SKU_PATH_NUM 185
461
462 #define MT7915_MAX_TWT_AGRT 16
463 #define MT7915_MAX_STA_TWT_AGRT 8
developerf520c8d2023-06-19 10:33:45 +0800464@@ -570,7 +571,8 @@ int mt7915_mcu_set_test_param(struct mt7915_dev *dev, u8 param, bool test_mode,
developerfe7be7f2022-12-13 21:40:24 +0800465 int mt7915_mcu_set_ser(struct mt7915_dev *dev, u8 action, u8 set, u8 band);
466 int mt7915_mcu_set_sku_en(struct mt7915_phy *phy, bool enable);
467 int mt7915_mcu_set_txpower_sku(struct mt7915_phy *phy);
468-int mt7915_mcu_get_txpower_sku(struct mt7915_phy *phy, s8 *txpower, int len);
469+int mt7915_mcu_get_txpower_sku(struct mt7915_phy *phy, s8 *txpower, int len,
470+ u8 category);
471 int mt7915_mcu_set_txpower_frame_min(struct mt7915_phy *phy, s8 txpower);
472 int mt7915_mcu_set_txpower_frame(struct mt7915_phy *phy,
473 struct ieee80211_vif *vif,
474--
developer2324aa22023-04-12 11:30:15 +08004752.18.0
developerfe7be7f2022-12-13 21:40:24 +0800476