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