blob: 0fcae6a2aa912c6783f619d93d78c75dd3ffcb4f [file] [log] [blame]
developer064da3c2023-06-13 15:57:26 +08001From 0d9ff0aa7afe37146c6015e416d9b944b4bb16f5 Mon Sep 17 00:00:00 2001
2From: "Allen.Ye" <allen.ye@mediatek.com>
3Date: Tue, 18 Apr 2023 15:56:22 +0800
4Subject: [PATCH 1011/1015] wifi: mt76: mt7996: add single sku
5
6Add single sku and default enable sku.
7
8Signed-off-by: Allen.Ye <allen.ye@mediatek.com>
9---
10 eeprom.c | 38 ++++++++++++++++++--
11 mt76.h | 10 ++++++
12 mt76_connac_mcu.c | 2 +-
13 mt7996/init.c | 2 ++
14 mt7996/main.c | 15 ++++++++
15 mt7996/mcu.c | 92 +++++++++++++++++++++++++++++++++++++++++++++++
16 mt7996/mcu.h | 12 +++++++
17 mt7996/mt7996.h | 2 ++
18 8 files changed, 169 insertions(+), 4 deletions(-)
19
20diff --git a/eeprom.c b/eeprom.c
21index 412740f0..3abefb5a 100644
22--- a/eeprom.c
23+++ b/eeprom.c
24@@ -301,6 +301,7 @@ mt76_apply_multi_array_limit(s8 *pwr, size_t pwr_len, s8 pwr_num,
25 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;
32@@ -308,16 +309,17 @@ s8 mt76_get_rate_power_limits(struct mt76_phy *phy,
33 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;
39 s8 max_power = 0;
40 s8 txs_delta;
41
42 if (!mcs_rates)
43- mcs_rates = 10;
44+ mcs_rates = 12;
45
46 memset(dest, target_power, sizeof(*dest));
47+ if (dest_path != NULL)
48+ memset(dest_path, 0, sizeof(*dest_path));
49
50 if (!IS_ENABLED(CONFIG_OF))
51 return target_power;
52@@ -365,11 +367,41 @@ s8 mt76_get_rate_power_limits(struct mt76_phy *phy,
53 ARRAY_SIZE(dest->mcs), val, len,
54 target_power, txs_delta, &max_power);
55
56- val = mt76_get_of_array(np, "rates-ru", &len, ru_rates + 1);
57+ val = mt76_get_of_array(np, "rates-ru", &len, ARRAY_SIZE(dest->ru[0]) + 1);
58 mt76_apply_multi_array_limit(dest->ru[0], ARRAY_SIZE(dest->ru[0]),
59 ARRAY_SIZE(dest->ru), val, len,
60 target_power, txs_delta, &max_power);
61
62+ val = mt76_get_of_array(np, "rates-eht-ru", &len, ARRAY_SIZE(dest->eht_ru[0]) + 1);
63+ mt76_apply_multi_array_limit(dest->eht_ru[0], ARRAY_SIZE(dest->eht_ru[0]),
64+ ARRAY_SIZE(dest->eht_ru), val, len,
65+ target_power, txs_delta, &max_power);
66+
67+ if (dest_path == NULL)
68+ return max_power;
69+
70+ val = mt76_get_of_array(np, "paths-cck", &len, ARRAY_SIZE(dest_path->cck));
71+ mt76_apply_array_limit(dest_path->cck, ARRAY_SIZE(dest_path->cck), val,
72+ target_power, txs_delta, &max_power);
73+
74+ val = mt76_get_of_array(np, "paths-ofdm", &len, ARRAY_SIZE(dest_path->ofdm));
75+ mt76_apply_array_limit(dest_path->ofdm, ARRAY_SIZE(dest_path->ofdm), val,
76+ target_power, txs_delta, &max_power);
77+
78+ val = mt76_get_of_array(np, "paths-ofdm-bf", &len, ARRAY_SIZE(dest_path->ofdm_bf));
79+ mt76_apply_array_limit(dest_path->ofdm_bf, ARRAY_SIZE(dest_path->ofdm_bf), val,
80+ target_power, txs_delta, &max_power);
81+
82+ val = mt76_get_of_array(np, "paths-ru", &len, ARRAY_SIZE(dest_path->ru[0]) + 1);
83+ mt76_apply_multi_array_limit(dest_path->ru[0], ARRAY_SIZE(dest_path->ru[0]),
84+ ARRAY_SIZE(dest_path->ru), val, len,
85+ target_power, txs_delta, &max_power);
86+
87+ val = mt76_get_of_array(np, "paths-ru-bf", &len, ARRAY_SIZE(dest_path->ru_bf[0]) + 1);
88+ mt76_apply_multi_array_limit(dest_path->ru_bf[0], ARRAY_SIZE(dest_path->ru_bf[0]),
89+ ARRAY_SIZE(dest_path->ru_bf), val, len,
90+ target_power, txs_delta, &max_power);
91+
92 return max_power;
93 }
94 EXPORT_SYMBOL_GPL(mt76_get_rate_power_limits);
95diff --git a/mt76.h b/mt76.h
96index 5b442691..8abb6f41 100644
97--- a/mt76.h
98+++ b/mt76.h
99@@ -911,6 +911,15 @@ struct mt76_power_limits {
100 s8 ofdm[8];
101 s8 mcs[4][10];
102 s8 ru[7][12];
103+ s8 eht_ru[16][16];
104+};
105+
106+struct mt76_power_path_limits {
107+ s8 cck[5];
108+ s8 ofdm[5];
109+ s8 ofdm_bf[4];
110+ s8 ru[16][15];
111+ s8 ru_bf[16][15];
112 };
113
114 struct mt76_ethtool_worker_info {
115@@ -1493,6 +1502,7 @@ void mt76_set_irq_mask(struct mt76_dev *dev, u32 addr, u32 clear, u32 set);
116 s8 mt76_get_rate_power_limits(struct mt76_phy *phy,
117 struct ieee80211_channel *chan,
118 struct mt76_power_limits *dest,
119+ struct mt76_power_path_limits *dest_path,
120 s8 target_power);
121
122 static inline bool mt76_queue_is_wed_rx(struct mt76_queue *q)
123diff --git a/mt76_connac_mcu.c b/mt76_connac_mcu.c
124index c24dac10..ca7b6a6f 100644
125--- a/mt76_connac_mcu.c
126+++ b/mt76_connac_mcu.c
127@@ -2235,7 +2235,7 @@ mt76_connac_mcu_rate_txpower_band(struct mt76_phy *phy,
128 sar_power = mt76_get_sar_power(phy, &chan, reg_power);
129
130 mt76_get_rate_power_limits(phy, &chan, &limits,
131- sar_power);
132+ NULL, sar_power);
133
134 tx_power_tlv.last_msg = ch_list[idx] == last_ch;
135 sku_tlbv.channel = ch_list[idx];
136diff --git a/mt7996/init.c b/mt7996/init.c
137index 31695090..a6caf4f1 100644
138--- a/mt7996/init.c
139+++ b/mt7996/init.c
140@@ -294,6 +294,7 @@ void mt7996_init_txpower(struct mt7996_dev *dev,
141 int nss_delta = mt76_tx_power_nss_delta(nss);
142 int pwr_delta = mt7996_eeprom_get_power_delta(dev, sband->band);
143 struct mt76_power_limits limits;
144+ struct mt76_power_path_limits limits_path;
145
146 for (i = 0; i < sband->n_channels; i++) {
147 struct ieee80211_channel *chan = &sband->channels[i];
148@@ -302,6 +303,7 @@ void mt7996_init_txpower(struct mt7996_dev *dev,
149 target_power += pwr_delta;
150 target_power = mt76_get_rate_power_limits(&dev->mphy, chan,
151 &limits,
152+ &limits_path,
153 target_power);
154 target_power += nss_delta;
155 target_power = DIV_ROUND_UP(target_power, 2);
156diff --git a/mt7996/main.c b/mt7996/main.c
157index d3d10fab..71c346cb 100644
158--- a/mt7996/main.c
159+++ b/mt7996/main.c
160@@ -77,6 +77,15 @@ int mt7996_run(struct ieee80211_hw *hw)
161 if (ret)
162 goto out;
163
164+#ifdef CONFIG_MTK_DEBUG
165+ ret = mt7996_mcu_set_tx_power_ctrl(phy, UNI_TXPOWER_SKU_POWER_LIMIT_CTRL,
166+ !dev->dbg.sku_disable);
167+#else
168+ ret = mt7996_mcu_set_tx_power_ctrl(phy, UNI_TXPOWER_SKU_POWER_LIMIT_CTRL, true);
169+#endif
170+ if (ret)
171+ goto out;
172+
173 set_bit(MT76_STATE_RUNNING, &phy->mt76->state);
174
175 ieee80211_queue_delayed_work(hw, &phy->mt76->mac_work,
176@@ -427,6 +436,12 @@ static int mt7996_config(struct ieee80211_hw *hw, u32 changed)
177 ieee80211_wake_queues(hw);
178 }
179
180+ if (changed & IEEE80211_CONF_CHANGE_POWER) {
181+ ret = mt7996_mcu_set_txpower_sku(phy);
182+ if (ret)
183+ return ret;
184+ }
185+
186 mutex_lock(&dev->mt76.mutex);
187
188 if (changed & IEEE80211_CONF_CHANGE_MONITOR) {
189diff --git a/mt7996/mcu.c b/mt7996/mcu.c
190index 53d2fc73..aefbdca6 100644
191--- a/mt7996/mcu.c
192+++ b/mt7996/mcu.c
193@@ -4616,6 +4616,98 @@ int mt7996_mcu_set_scs(struct mt7996_phy *phy, u8 enable)
194 &req, sizeof(req), false);
195 }
196
197+int mt7996_mcu_set_txpower_sku(struct mt7996_phy *phy)
198+{
199+#define TX_POWER_LIMIT_TABLE_RATE 0
200+#define TX_POWER_LIMIT_TABLE_PATH 1
201+ struct mt7996_dev *dev = phy->dev;
202+ struct mt76_phy *mphy = phy->mt76;
203+ struct ieee80211_hw *hw = mphy->hw;
204+ struct tx_power_limit_table_ctrl {
205+ u8 __rsv1[4];
206+
207+ __le16 tag;
208+ __le16 len;
209+ u8 power_ctrl_id;
210+ u8 power_limit_type;
211+ u8 band_idx;
212+ } __packed req = {
213+ .tag = cpu_to_le16(UNI_TXPOWER_POWER_LIMIT_TABLE_CTRL),
214+ .len = cpu_to_le16(sizeof(req) + MT7996_SKU_PATH_NUM - 4),
215+ .power_ctrl_id = UNI_TXPOWER_POWER_LIMIT_TABLE_CTRL,
216+ .power_limit_type = TX_POWER_LIMIT_TABLE_RATE,
217+ .band_idx = phy->mt76->band_idx,
218+ };
219+
220+ int i, ret, tx_power;
221+ const u8 *len = mt7996_sku_group_len;
222+ struct mt76_power_limits la = {};
223+ struct mt76_power_path_limits la_path = {};
224+ struct sk_buff *skb;
225+
226+ tx_power = mt7996_get_power_bound(phy, hw->conf.power_level);
227+ tx_power = mt76_get_rate_power_limits(mphy, mphy->chandef.chan,
228+ &la, &la_path, tx_power);
229+ mphy->txpower_cur = tx_power;
230+
231+ skb = mt76_mcu_msg_alloc(&dev->mt76, NULL,
232+ sizeof(req) + MT7996_SKU_PATH_NUM);
233+ if (!skb)
234+ return -ENOMEM;
235+
236+ skb_put_data(skb, &req, sizeof(req));
237+ skb_put_data(skb, &la.cck, len[SKU_CCK] + len[SKU_OFDM]);
238+
239+ skb_put_data(skb, &la.mcs[0], len[SKU_HT20]);
240+ skb_put_data(skb, &la.mcs[1], len[SKU_HT40]);
241+
242+ /* vht */
243+ for (i = 0; i < 4; i++) {
244+ skb_put_data(skb, &la.mcs[i], sizeof(la.mcs[i]));
245+ skb_put_zero(skb, 2); /* padding */
246+ }
247+
248+ /* he */
249+ skb_put_data(skb, &la.ru[0], sizeof(la.ru));
250+
251+ /* eht */
252+ skb_put_data(skb, &la.eht_ru[0], sizeof(la.eht_ru));
253+
254+ /* padding */
255+ skb_put_zero(skb, MT7996_SKU_PATH_NUM - MT7996_SKU_RATE_NUM);
256+
257+ ret = mt76_mcu_skb_send_msg(&dev->mt76, skb,
258+ MCU_WM_UNI_CMD(TXPOWER), true);
259+ if (ret)
260+ return ret;
261+
262+ /* only set per-path power table when it's configured */
263+ if (!la_path.ofdm[0])
264+ return 0;
265+
266+ skb = mt76_mcu_msg_alloc(&dev->mt76, NULL,
267+ sizeof(req) + MT7996_SKU_PATH_NUM);
268+ if (!skb)
269+ return -ENOMEM;
270+ req.power_limit_type = TX_POWER_LIMIT_TABLE_PATH;
271+
272+ skb_put_data(skb, &req, sizeof(req));
273+ skb_put_data(skb, &la_path.cck, sizeof(la_path.cck));
274+ skb_put_data(skb, &la_path.ofdm, sizeof(la_path.ofdm));
275+ skb_put_data(skb, &la_path.ofdm_bf, sizeof(la_path.ofdm_bf));
276+
277+ for (i = 0; i < 32; i++) {
278+ bool bf = i % 2;
279+ u8 idx = i / 2;
280+ s8 *buf = bf ? la_path.ru_bf[idx] : la_path.ru[idx];
281+
282+ skb_put_data(skb, buf, sizeof(la_path.ru[0]));
283+ }
284+
285+ return mt76_mcu_skb_send_msg(&dev->mt76, skb,
286+ MCU_WM_UNI_CMD(TXPOWER), true);
287+}
288+
289 #ifdef CONFIG_MTK_VENDOR
290 void mt7996_set_wireless_vif(void *data, u8 *mac, struct ieee80211_vif *vif)
291 {
292diff --git a/mt7996/mcu.h b/mt7996/mcu.h
293index f32ac153..1d2b7c58 100644
294--- a/mt7996/mcu.h
295+++ b/mt7996/mcu.h
296@@ -657,6 +657,18 @@ enum {
297 #define MT7996_MAX_BSS_OFFLOAD_SIZE (MT7996_MAX_BEACON_SIZE + \
298 MT7996_BEACON_UPDATE_SIZE)
299
300+static inline s8
301+mt7996_get_power_bound(struct mt7996_phy *phy, s8 txpower)
302+{
303+ struct mt76_phy *mphy = phy->mt76;
304+ int n_chains = hweight8(mphy->antenna_mask);
305+
306+ txpower = mt76_get_sar_power(mphy, mphy->chandef.chan, txpower * 2);
307+ txpower -= mt76_tx_power_nss_delta(n_chains);
308+
309+ return txpower;
310+}
311+
312 enum {
313 UNI_BAND_CONFIG_RADIO_ENABLE,
314 UNI_BAND_CONFIG_RTS_THRESHOLD = 0x08,
315diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
316index abdbb1ef..d15bd950 100644
317--- a/mt7996/mt7996.h
318+++ b/mt7996/mt7996.h
319@@ -61,6 +61,7 @@
320 #define MT7996_BUILD_TIME_LEN 24
321
322 #define MT7996_SKU_RATE_NUM 417
323+#define MT7996_SKU_PATH_NUM 494
324
325 struct mt7996_vif;
326 struct mt7996_sta;
327@@ -610,6 +611,7 @@ int mt7996_mcu_set_tx_power_ctrl(struct mt7996_phy *phy, u8 power_ctrl_id, u8 da
328 int mt7996_mcu_get_tx_power_info(struct mt7996_phy *phy, u8 category, void *event);
329 int mt7996_mcu_apply_group_cal(struct mt7996_dev *dev);
330 int mt7996_mcu_apply_tx_dpd(struct mt7996_phy *phy);
331+int mt7996_mcu_set_txpower_sku(struct mt7996_phy *phy);
332 int mt7996_mcu_set_scs(struct mt7996_phy *phy, u8 enable);
333 void mt7996_mcu_scs_sta_poll(struct work_struct *work);
334 #ifdef CONFIG_NL80211_TESTMODE
335--
3362.39.2
337