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