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