xref: /linux/drivers/net/wireless/mediatek/mt76/mt7615/eeprom.c (revision 0c7c237b1c35011ef0b8d30c1d5c20bc6ae7b69b)
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 
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 
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 
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 
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
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_2GHZ:
132 		dev->mphy.cap.has_2ghz = true;
133 		break;
134 	case MT_EE_DBDC:
135 		dev->dbdc_support = true;
136 		fallthrough;
137 	default:
138 		dev->mphy.cap.has_2ghz = true;
139 		dev->mphy.cap.has_5ghz = true;
140 		break;
141 	}
142 }
143 
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 
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 
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 
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 
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 
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 
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 
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