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