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 		return 0;
88 	default:
89 		return -EINVAL;
90 	}
91 }
92 
93 static void mt7615_eeprom_parse_hw_cap(struct mt7615_dev *dev)
94 {
95 	u8 val, *eeprom = dev->mt76.eeprom.data;
96 	u8 tx_mask, rx_mask, max_nss;
97 
98 	val = FIELD_GET(MT_EE_NIC_WIFI_CONF_BAND_SEL,
99 			eeprom[MT_EE_WIFI_CONF]);
100 	switch (val) {
101 	case MT_EE_5GHZ:
102 		dev->mt76.cap.has_5ghz = true;
103 		break;
104 	case MT_EE_2GHZ:
105 		dev->mt76.cap.has_2ghz = true;
106 		break;
107 	default:
108 		dev->mt76.cap.has_2ghz = true;
109 		dev->mt76.cap.has_5ghz = true;
110 		break;
111 	}
112 
113 	/* read tx-rx mask from eeprom */
114 	val = mt76_rr(dev, MT_TOP_STRAP_STA);
115 	max_nss = val & MT_TOP_3NSS ? 3 : 4;
116 
117 	rx_mask =  FIELD_GET(MT_EE_NIC_CONF_RX_MASK,
118 			     eeprom[MT_EE_NIC_CONF_0]);
119 	if (!rx_mask || rx_mask > max_nss)
120 		rx_mask = max_nss;
121 
122 	tx_mask =  FIELD_GET(MT_EE_NIC_CONF_TX_MASK,
123 			     eeprom[MT_EE_NIC_CONF_0]);
124 	if (!tx_mask || tx_mask > max_nss)
125 		tx_mask = max_nss;
126 
127 	dev->mt76.chainmask = tx_mask << 8 | rx_mask;
128 	dev->mt76.antenna_mask = BIT(tx_mask) - 1;
129 }
130 
131 int mt7615_eeprom_get_power_index(struct mt7615_dev *dev,
132 				  struct ieee80211_channel *chan,
133 				  u8 chain_idx)
134 {
135 	int index;
136 
137 	if (chain_idx > 3)
138 		return -EINVAL;
139 
140 	/* TSSI disabled */
141 	if (mt7615_ext_pa_enabled(dev, chan->band)) {
142 		if (chan->band == NL80211_BAND_2GHZ)
143 			return MT_EE_EXT_PA_2G_TARGET_POWER;
144 		else
145 			return MT_EE_EXT_PA_5G_TARGET_POWER;
146 	}
147 
148 	/* TSSI enabled */
149 	if (chan->band == NL80211_BAND_2GHZ) {
150 		index = MT_EE_TX0_2G_TARGET_POWER + chain_idx * 6;
151 	} else {
152 		int group = mt7615_get_channel_group(chan->hw_value);
153 
154 		switch (chain_idx) {
155 		case 1:
156 			index = MT_EE_TX1_5G_G0_TARGET_POWER;
157 			break;
158 		case 2:
159 			index = MT_EE_TX2_5G_G0_TARGET_POWER;
160 			break;
161 		case 3:
162 			index = MT_EE_TX3_5G_G0_TARGET_POWER;
163 			break;
164 		case 0:
165 		default:
166 			index = MT_EE_TX0_5G_G0_TARGET_POWER;
167 			break;
168 		}
169 		index += 5 * group;
170 	}
171 
172 	return index;
173 }
174 
175 static void mt7615_apply_cal_free_data(struct mt7615_dev *dev)
176 {
177 	static const u16 ical[] = {
178 		0x53, 0x54, 0x55, 0x56, 0x57, 0x5c, 0x5d, 0x62, 0x63, 0x68,
179 		0x69, 0x6e, 0x6f, 0x73, 0x74, 0x78, 0x79, 0x82, 0x83, 0x87,
180 		0x88, 0x8c, 0x8d, 0x91, 0x92, 0x96, 0x97, 0x9b, 0x9c, 0xa0,
181 		0xa1, 0xaa, 0xab, 0xaf, 0xb0, 0xb4, 0xb5, 0xb9, 0xba, 0xf4,
182 		0xf7, 0xff,
183 		0x140, 0x141, 0x145, 0x146, 0x14a, 0x14b, 0x154, 0x155, 0x159,
184 		0x15a, 0x15e, 0x15f, 0x163, 0x164, 0x168, 0x169, 0x16d, 0x16e,
185 		0x172, 0x173, 0x17c, 0x17d, 0x181, 0x182, 0x186, 0x187, 0x18b,
186 		0x18c
187 	};
188 	static const u16 ical_nocheck[] = {
189 		0x110, 0x111, 0x112, 0x113, 0x114, 0x115, 0x116, 0x117, 0x118,
190 		0x1b5, 0x1b6, 0x1b7, 0x3ac, 0x3ad, 0x3ae, 0x3af, 0x3b0, 0x3b1,
191 		0x3b2
192 	};
193 	u8 *eeprom = dev->mt76.eeprom.data;
194 	u8 *otp = dev->mt76.otp.data;
195 	int i;
196 
197 	if (!otp)
198 		return;
199 
200 	for (i = 0; i < ARRAY_SIZE(ical); i++)
201 		if (!otp[ical[i]])
202 			return;
203 
204 	for (i = 0; i < ARRAY_SIZE(ical); i++)
205 		eeprom[ical[i]] = otp[ical[i]];
206 
207 	for (i = 0; i < ARRAY_SIZE(ical_nocheck); i++)
208 		eeprom[ical_nocheck[i]] = otp[ical_nocheck[i]];
209 }
210 
211 int mt7615_eeprom_init(struct mt7615_dev *dev)
212 {
213 	int ret;
214 
215 	ret = mt7615_eeprom_load(dev);
216 	if (ret < 0)
217 		return ret;
218 
219 	ret = mt7615_check_eeprom(&dev->mt76);
220 	if (ret && dev->mt76.otp.data)
221 		memcpy(dev->mt76.eeprom.data, dev->mt76.otp.data,
222 		       MT7615_EEPROM_SIZE);
223 	else
224 		mt7615_apply_cal_free_data(dev);
225 
226 	mt7615_eeprom_parse_hw_cap(dev);
227 	memcpy(dev->mt76.macaddr, dev->mt76.eeprom.data + MT_EE_MAC_ADDR,
228 	       ETH_ALEN);
229 
230 	mt76_eeprom_override(&dev->mt76);
231 
232 	return 0;
233 }
234