1 // SPDX-License-Identifier: ISC
2 /* Copyright (C) 2019 MediaTek Inc.
3 *
4 * Author: Ryder Lee <ryder.lee@mediatek.com>
5 * Felix Fietkau <nbd@nbd.name>
6 */
7
8 #include <linux/of.h>
9 #if defined(__FreeBSD__)
10 #include <linux/delay.h>
11 #endif
12 #include "mt7615.h"
13 #include "eeprom.h"
14
mt7615_efuse_read(struct mt7615_dev * dev,u32 base,u16 addr,u8 * data)15 static int mt7615_efuse_read(struct mt7615_dev *dev, u32 base,
16 u16 addr, u8 *data)
17 {
18 u32 val;
19 int i;
20
21 val = mt76_rr(dev, base + MT_EFUSE_CTRL);
22 val &= ~(MT_EFUSE_CTRL_AIN | MT_EFUSE_CTRL_MODE);
23 val |= FIELD_PREP(MT_EFUSE_CTRL_AIN, addr & ~0xf);
24 val |= MT_EFUSE_CTRL_KICK;
25 mt76_wr(dev, base + MT_EFUSE_CTRL, val);
26
27 if (!mt76_poll(dev, base + MT_EFUSE_CTRL, MT_EFUSE_CTRL_KICK, 0, 1000))
28 return -ETIMEDOUT;
29
30 udelay(2);
31
32 val = mt76_rr(dev, base + MT_EFUSE_CTRL);
33 if ((val & MT_EFUSE_CTRL_AOUT) == MT_EFUSE_CTRL_AOUT ||
34 WARN_ON_ONCE(!(val & MT_EFUSE_CTRL_VALID))) {
35 memset(data, 0x0, 16);
36 return 0;
37 }
38
39 for (i = 0; i < 4; i++) {
40 val = mt76_rr(dev, base + MT_EFUSE_RDATA(i));
41 put_unaligned_le32(val, data + 4 * i);
42 }
43
44 return 0;
45 }
46
mt7615_efuse_init(struct mt7615_dev * dev,u32 base)47 static int mt7615_efuse_init(struct mt7615_dev *dev, u32 base)
48 {
49 int i, len = MT7615_EEPROM_SIZE;
50 void *buf;
51 u32 val;
52
53 if (is_mt7663(&dev->mt76))
54 len = MT7663_EEPROM_SIZE;
55
56 val = mt76_rr(dev, base + MT_EFUSE_BASE_CTRL);
57 if (val & MT_EFUSE_BASE_CTRL_EMPTY)
58 return 0;
59
60 dev->mt76.otp.data = devm_kzalloc(dev->mt76.dev, len, GFP_KERNEL);
61 dev->mt76.otp.size = len;
62 if (!dev->mt76.otp.data)
63 return -ENOMEM;
64
65 buf = dev->mt76.otp.data;
66 for (i = 0; i + 16 <= len; i += 16) {
67 int ret;
68
69 #if defined(__linux__)
70 ret = mt7615_efuse_read(dev, base, i, buf + i);
71 #elif defined(__FreeBSD__)
72 ret = mt7615_efuse_read(dev, base, i, (u8 *)buf + i);
73 #endif
74 if (ret)
75 return ret;
76 }
77
78 return 0;
79 }
80
mt7615_eeprom_load(struct mt7615_dev * dev,u32 addr)81 static int mt7615_eeprom_load(struct mt7615_dev *dev, u32 addr)
82 {
83 int ret;
84
85 BUILD_BUG_ON(MT7615_EEPROM_FULL_SIZE < MT7663_EEPROM_SIZE);
86
87 ret = mt76_eeprom_init(&dev->mt76, MT7615_EEPROM_FULL_SIZE);
88 if (ret < 0)
89 return ret;
90
91 return mt7615_efuse_init(dev, addr);
92 }
93
mt7615_check_eeprom(struct mt76_dev * dev)94 static int mt7615_check_eeprom(struct mt76_dev *dev)
95 {
96 u16 val = get_unaligned_le16(dev->eeprom.data);
97
98 switch (val) {
99 case 0x7615:
100 case 0x7622:
101 case 0x7663:
102 return 0;
103 default:
104 return -EINVAL;
105 }
106 }
107
108 static void
mt7615_eeprom_parse_hw_band_cap(struct mt7615_dev * dev)109 mt7615_eeprom_parse_hw_band_cap(struct mt7615_dev *dev)
110 {
111 u8 val, *eeprom = dev->mt76.eeprom.data;
112
113 if (is_mt7663(&dev->mt76)) {
114 /* dual band */
115 dev->mphy.cap.has_2ghz = true;
116 dev->mphy.cap.has_5ghz = true;
117 return;
118 }
119
120 if (is_mt7622(&dev->mt76)) {
121 /* 2GHz only */
122 dev->mphy.cap.has_2ghz = true;
123 return;
124 }
125
126 if (is_mt7611(&dev->mt76)) {
127 /* 5GHz only */
128 dev->mphy.cap.has_5ghz = true;
129 return;
130 }
131
132 val = FIELD_GET(MT_EE_NIC_WIFI_CONF_BAND_SEL,
133 eeprom[MT_EE_WIFI_CONF]);
134 switch (val) {
135 case MT_EE_5GHZ:
136 dev->mphy.cap.has_5ghz = true;
137 break;
138 case MT_EE_DBDC:
139 dev->dbdc_support = true;
140 fallthrough;
141 case MT_EE_2GHZ:
142 dev->mphy.cap.has_2ghz = true;
143 break;
144 default:
145 dev->mphy.cap.has_2ghz = true;
146 dev->mphy.cap.has_5ghz = true;
147 break;
148 }
149 }
150
mt7615_eeprom_parse_hw_cap(struct mt7615_dev * dev)151 static void mt7615_eeprom_parse_hw_cap(struct mt7615_dev *dev)
152 {
153 u8 *eeprom = dev->mt76.eeprom.data;
154 u8 tx_mask, max_nss;
155
156 mt7615_eeprom_parse_hw_band_cap(dev);
157
158 if (is_mt7663(&dev->mt76)) {
159 max_nss = 2;
160 tx_mask = FIELD_GET(MT_EE_HW_CONF1_TX_MASK,
161 eeprom[MT7663_EE_HW_CONF1]);
162 } else {
163 u32 val;
164
165 /* read tx-rx mask from eeprom */
166 val = mt76_rr(dev, MT_TOP_STRAP_STA);
167 max_nss = val & MT_TOP_3NSS ? 3 : 4;
168
169 tx_mask = FIELD_GET(MT_EE_NIC_CONF_TX_MASK,
170 eeprom[MT_EE_NIC_CONF_0]);
171 }
172 if (!tx_mask || tx_mask > max_nss)
173 tx_mask = max_nss;
174
175 dev->chainmask = BIT(tx_mask) - 1;
176 dev->mphy.antenna_mask = dev->chainmask;
177 dev->mphy.chainmask = dev->chainmask;
178 }
179
mt7663_eeprom_get_target_power_index(struct mt7615_dev * dev,struct ieee80211_channel * chan,u8 chain_idx)180 static int mt7663_eeprom_get_target_power_index(struct mt7615_dev *dev,
181 struct ieee80211_channel *chan,
182 u8 chain_idx)
183 {
184 int index, group;
185
186 if (chain_idx > 1)
187 return -EINVAL;
188
189 if (chan->band == NL80211_BAND_2GHZ)
190 return MT7663_EE_TX0_2G_TARGET_POWER + (chain_idx << 4);
191
192 group = mt7615_get_channel_group(chan->hw_value);
193 if (chain_idx == 1)
194 index = MT7663_EE_TX1_5G_G0_TARGET_POWER;
195 else
196 index = MT7663_EE_TX0_5G_G0_TARGET_POWER;
197
198 return index + group * 3;
199 }
200
mt7615_eeprom_get_target_power_index(struct mt7615_dev * dev,struct ieee80211_channel * chan,u8 chain_idx)201 int mt7615_eeprom_get_target_power_index(struct mt7615_dev *dev,
202 struct ieee80211_channel *chan,
203 u8 chain_idx)
204 {
205 int index;
206
207 if (is_mt7663(&dev->mt76))
208 return mt7663_eeprom_get_target_power_index(dev, chan,
209 chain_idx);
210
211 if (chain_idx > 3)
212 return -EINVAL;
213
214 /* TSSI disabled */
215 if (mt7615_ext_pa_enabled(dev, chan->band)) {
216 if (chan->band == NL80211_BAND_2GHZ)
217 return MT_EE_EXT_PA_2G_TARGET_POWER;
218 else
219 return MT_EE_EXT_PA_5G_TARGET_POWER;
220 }
221
222 /* TSSI enabled */
223 if (chan->band == NL80211_BAND_2GHZ) {
224 index = MT_EE_TX0_2G_TARGET_POWER + chain_idx * 6;
225 } else {
226 int group = mt7615_get_channel_group(chan->hw_value);
227
228 switch (chain_idx) {
229 case 1:
230 index = MT_EE_TX1_5G_G0_TARGET_POWER;
231 break;
232 case 2:
233 index = MT_EE_TX2_5G_G0_TARGET_POWER;
234 break;
235 case 3:
236 index = MT_EE_TX3_5G_G0_TARGET_POWER;
237 break;
238 case 0:
239 default:
240 index = MT_EE_TX0_5G_G0_TARGET_POWER;
241 break;
242 }
243 index += 5 * group;
244 }
245
246 return index;
247 }
248
mt7615_eeprom_get_power_delta_index(struct mt7615_dev * dev,enum nl80211_band band)249 int mt7615_eeprom_get_power_delta_index(struct mt7615_dev *dev,
250 enum nl80211_band band)
251 {
252 /* assume the first rate has the highest power offset */
253 if (is_mt7663(&dev->mt76)) {
254 if (band == NL80211_BAND_2GHZ)
255 return MT_EE_TX0_5G_G0_TARGET_POWER;
256 else
257 return MT7663_EE_5G_RATE_POWER;
258 }
259
260 if (band == NL80211_BAND_2GHZ)
261 return MT_EE_2G_RATE_POWER;
262 else
263 return MT_EE_5G_RATE_POWER;
264 }
265
266 #if defined(__linux__)
mt7615_apply_cal_free_data(struct mt7615_dev * dev)267 static void mt7615_apply_cal_free_data(struct mt7615_dev *dev)
268 {
269 static const u16 ical[] = {
270 0x53, 0x54, 0x55, 0x56, 0x57, 0x5c, 0x5d, 0x62, 0x63, 0x68,
271 0x69, 0x6e, 0x6f, 0x73, 0x74, 0x78, 0x79, 0x82, 0x83, 0x87,
272 0x88, 0x8c, 0x8d, 0x91, 0x92, 0x96, 0x97, 0x9b, 0x9c, 0xa0,
273 0xa1, 0xaa, 0xab, 0xaf, 0xb0, 0xb4, 0xb5, 0xb9, 0xba, 0xf4,
274 0xf7, 0xff,
275 0x140, 0x141, 0x145, 0x146, 0x14a, 0x14b, 0x154, 0x155, 0x159,
276 0x15a, 0x15e, 0x15f, 0x163, 0x164, 0x168, 0x169, 0x16d, 0x16e,
277 0x172, 0x173, 0x17c, 0x17d, 0x181, 0x182, 0x186, 0x187, 0x18b,
278 0x18c
279 };
280 static const u16 ical_nocheck[] = {
281 0x110, 0x111, 0x112, 0x113, 0x114, 0x115, 0x116, 0x117, 0x118,
282 0x1b5, 0x1b6, 0x1b7, 0x3ac, 0x3ad, 0x3ae, 0x3af, 0x3b0, 0x3b1,
283 0x3b2
284 };
285 u8 *eeprom = dev->mt76.eeprom.data;
286 u8 *otp = dev->mt76.otp.data;
287 int i;
288
289 if (!otp)
290 return;
291
292 for (i = 0; i < ARRAY_SIZE(ical); i++)
293 if (!otp[ical[i]])
294 return;
295
296 for (i = 0; i < ARRAY_SIZE(ical); i++)
297 eeprom[ical[i]] = otp[ical[i]];
298
299 for (i = 0; i < ARRAY_SIZE(ical_nocheck); i++)
300 eeprom[ical_nocheck[i]] = otp[ical_nocheck[i]];
301 }
302
mt7622_apply_cal_free_data(struct mt7615_dev * dev)303 static void mt7622_apply_cal_free_data(struct mt7615_dev *dev)
304 {
305 static const u16 ical[] = {
306 0x53, 0x54, 0x55, 0x56, 0xf4, 0xf7, 0x144, 0x156, 0x15b
307 };
308 u8 *eeprom = dev->mt76.eeprom.data;
309 u8 *otp = dev->mt76.otp.data;
310 int i;
311
312 if (!otp)
313 return;
314
315 for (i = 0; i < ARRAY_SIZE(ical); i++) {
316 if (!otp[ical[i]])
317 continue;
318
319 eeprom[ical[i]] = otp[ical[i]];
320 }
321 }
322 #endif
323
mt7615_cal_free_data(struct mt7615_dev * dev)324 static void mt7615_cal_free_data(struct mt7615_dev *dev)
325 {
326 #if defined(__linux__)
327 struct device_node *np = dev->mt76.dev->of_node;
328
329 if (!np || !of_property_read_bool(np, "mediatek,eeprom-merge-otp"))
330 return;
331
332 switch (mt76_chip(&dev->mt76)) {
333 case 0x7622:
334 mt7622_apply_cal_free_data(dev);
335 break;
336 case 0x7615:
337 case 0x7611:
338 mt7615_apply_cal_free_data(dev);
339 break;
340 }
341 #endif
342 }
343
mt7615_eeprom_init(struct mt7615_dev * dev,u32 addr)344 int mt7615_eeprom_init(struct mt7615_dev *dev, u32 addr)
345 {
346 int ret;
347
348 ret = mt7615_eeprom_load(dev, addr);
349 if (ret < 0)
350 return ret;
351
352 ret = mt7615_check_eeprom(&dev->mt76);
353 if (ret && dev->mt76.otp.data) {
354 memcpy(dev->mt76.eeprom.data, dev->mt76.otp.data,
355 dev->mt76.otp.size);
356 } else {
357 dev->flash_eeprom = true;
358 mt7615_cal_free_data(dev);
359 }
360
361 mt7615_eeprom_parse_hw_cap(dev);
362 #if defined(__linux__)
363 memcpy(dev->mphy.macaddr, dev->mt76.eeprom.data + MT_EE_MAC_ADDR,
364 #elif defined(__FreeBSD__)
365 memcpy(dev->mphy.macaddr, (u8 *)dev->mt76.eeprom.data + MT_EE_MAC_ADDR,
366 #endif
367 ETH_ALEN);
368
369 mt76_eeprom_override(&dev->mphy);
370
371 return 0;
372 }
373 EXPORT_SYMBOL_GPL(mt7615_eeprom_init);
374