1 // SPDX-License-Identifier: ISC
2 /*
3  * Copyright (C) 2022 MediaTek Inc.
4  */
5 
6 #include <linux/firmware.h>
7 #include "mt7996.h"
8 #include "eeprom.h"
9 
10 static int mt7996_check_eeprom(struct mt7996_dev *dev)
11 {
12 	u8 *eeprom = dev->mt76.eeprom.data;
13 	u16 val = get_unaligned_le16(eeprom);
14 
15 	switch (val) {
16 	case 0x7990:
17 		return 0;
18 	default:
19 		return -EINVAL;
20 	}
21 }
22 
23 static char *mt7996_eeprom_name(struct mt7996_dev *dev)
24 {
25 	/* reserve for future variants */
26 	return MT7996_EEPROM_DEFAULT;
27 }
28 
29 static int
30 mt7996_eeprom_load_default(struct mt7996_dev *dev)
31 {
32 	u8 *eeprom = dev->mt76.eeprom.data;
33 	const struct firmware *fw = NULL;
34 	int ret;
35 
36 	ret = request_firmware(&fw, mt7996_eeprom_name(dev), dev->mt76.dev);
37 	if (ret)
38 		return ret;
39 
40 	if (!fw || !fw->data) {
41 		dev_err(dev->mt76.dev, "Invalid default bin\n");
42 		ret = -EINVAL;
43 		goto out;
44 	}
45 
46 	memcpy(eeprom, fw->data, MT7996_EEPROM_SIZE);
47 	dev->flash_mode = true;
48 
49 out:
50 	release_firmware(fw);
51 
52 	return ret;
53 }
54 
55 static int mt7996_eeprom_load(struct mt7996_dev *dev)
56 {
57 	int ret;
58 
59 	ret = mt76_eeprom_init(&dev->mt76, MT7996_EEPROM_SIZE);
60 	if (ret < 0)
61 		return ret;
62 
63 	if (ret) {
64 		dev->flash_mode = true;
65 	} else {
66 		u8 free_block_num;
67 		u32 block_num, i;
68 
69 		/* TODO: check free block event */
70 		mt7996_mcu_get_eeprom_free_block(dev, &free_block_num);
71 		/* efuse info not enough */
72 		if (free_block_num >= 59)
73 			return -EINVAL;
74 
75 		/* read eeprom data from efuse */
76 		block_num = DIV_ROUND_UP(MT7996_EEPROM_SIZE, MT7996_EEPROM_BLOCK_SIZE);
77 		for (i = 0; i < block_num; i++)
78 			mt7996_mcu_get_eeprom(dev, i * MT7996_EEPROM_BLOCK_SIZE);
79 	}
80 
81 	return mt7996_check_eeprom(dev);
82 }
83 
84 static int mt7996_eeprom_parse_band_config(struct mt7996_phy *phy)
85 {
86 	u8 *eeprom = phy->dev->mt76.eeprom.data;
87 	u32 val = eeprom[MT_EE_WIFI_CONF];
88 	int ret = 0;
89 
90 	switch (phy->mt76->band_idx) {
91 	case MT_BAND1:
92 		val = FIELD_GET(MT_EE_WIFI_CONF1_BAND_SEL, val);
93 		break;
94 	case MT_BAND2:
95 		val = eeprom[MT_EE_WIFI_CONF + 1];
96 		val = FIELD_GET(MT_EE_WIFI_CONF2_BAND_SEL, val);
97 		break;
98 	default:
99 		val = FIELD_GET(MT_EE_WIFI_CONF0_BAND_SEL, val);
100 		break;
101 	}
102 
103 	switch (val) {
104 	case MT_EE_BAND_SEL_2GHZ:
105 		phy->mt76->cap.has_2ghz = true;
106 		break;
107 	case MT_EE_BAND_SEL_5GHZ:
108 		phy->mt76->cap.has_5ghz = true;
109 		break;
110 	case MT_EE_BAND_SEL_6GHZ:
111 		phy->mt76->cap.has_6ghz = true;
112 		break;
113 	case MT_EE_BAND_SEL_5GHZ_6GHZ:
114 		phy->mt76->cap.has_5ghz = true;
115 		phy->mt76->cap.has_6ghz = true;
116 		break;
117 	default:
118 		ret = -EINVAL;
119 		break;
120 	}
121 
122 	return ret;
123 }
124 
125 int mt7996_eeprom_parse_hw_cap(struct mt7996_dev *dev, struct mt7996_phy *phy)
126 {
127 	u8 path, nss, band_idx = phy->mt76->band_idx;
128 	u8 *eeprom = dev->mt76.eeprom.data;
129 	struct mt76_phy *mphy = phy->mt76;
130 
131 	switch (band_idx) {
132 	case MT_BAND1:
133 		path = FIELD_GET(MT_EE_WIFI_CONF2_TX_PATH_BAND1,
134 				 eeprom[MT_EE_WIFI_CONF + 2]);
135 		nss = FIELD_GET(MT_EE_WIFI_CONF5_STREAM_NUM_BAND1,
136 				eeprom[MT_EE_WIFI_CONF + 5]);
137 		break;
138 	case MT_BAND2:
139 		path = FIELD_GET(MT_EE_WIFI_CONF2_TX_PATH_BAND2,
140 				 eeprom[MT_EE_WIFI_CONF + 2]);
141 		nss = FIELD_GET(MT_EE_WIFI_CONF5_STREAM_NUM_BAND2,
142 				eeprom[MT_EE_WIFI_CONF + 5]);
143 		break;
144 	default:
145 		path = FIELD_GET(MT_EE_WIFI_CONF1_TX_PATH_BAND0,
146 				 eeprom[MT_EE_WIFI_CONF + 1]);
147 		nss = FIELD_GET(MT_EE_WIFI_CONF4_STREAM_NUM_BAND0,
148 				eeprom[MT_EE_WIFI_CONF + 4]);
149 		break;
150 	}
151 
152 	if (!path || path > 4)
153 		path = 4;
154 
155 	nss = min_t(u8, min_t(u8, 4, nss), path);
156 
157 	mphy->antenna_mask = BIT(nss) - 1;
158 	mphy->chainmask = (BIT(path) - 1) << dev->chainshift[band_idx];
159 	dev->chainmask |= mphy->chainmask;
160 	if (band_idx < MT_BAND2)
161 		dev->chainshift[band_idx + 1] = dev->chainshift[band_idx] +
162 						hweight16(mphy->chainmask);
163 
164 	return mt7996_eeprom_parse_band_config(phy);
165 }
166 
167 int mt7996_eeprom_init(struct mt7996_dev *dev)
168 {
169 	int ret;
170 
171 	ret = mt7996_eeprom_load(dev);
172 	if (ret < 0) {
173 		if (ret != -EINVAL)
174 			return ret;
175 
176 		dev_warn(dev->mt76.dev, "eeprom load fail, use default bin\n");
177 		ret = mt7996_eeprom_load_default(dev);
178 		if (ret)
179 			return ret;
180 	}
181 
182 	ret = mt7996_eeprom_parse_hw_cap(dev, &dev->phy);
183 	if (ret < 0)
184 		return ret;
185 
186 	memcpy(dev->mphy.macaddr, dev->mt76.eeprom.data + MT_EE_MAC_ADDR, ETH_ALEN);
187 	mt76_eeprom_override(&dev->mphy);
188 
189 	return 0;
190 }
191 
192 int mt7996_eeprom_get_target_power(struct mt7996_dev *dev,
193 				   struct ieee80211_channel *chan)
194 {
195 	u8 *eeprom = dev->mt76.eeprom.data;
196 	int target_power;
197 
198 	if (chan->band == NL80211_BAND_5GHZ)
199 		target_power = eeprom[MT_EE_TX0_POWER_5G +
200 				      mt7996_get_channel_group_5g(chan->hw_value)];
201 	else if (chan->band == NL80211_BAND_6GHZ)
202 		target_power = eeprom[MT_EE_TX0_POWER_6G +
203 				      mt7996_get_channel_group_6g(chan->hw_value)];
204 	else
205 		target_power = eeprom[MT_EE_TX0_POWER_2G];
206 
207 	return target_power;
208 }
209 
210 s8 mt7996_eeprom_get_power_delta(struct mt7996_dev *dev, int band)
211 {
212 	u8 *eeprom = dev->mt76.eeprom.data;
213 	u32 val;
214 	s8 delta;
215 
216 	if (band == NL80211_BAND_5GHZ)
217 		val = eeprom[MT_EE_RATE_DELTA_5G];
218 	else if (band == NL80211_BAND_6GHZ)
219 		val = eeprom[MT_EE_RATE_DELTA_6G];
220 	else
221 		val = eeprom[MT_EE_RATE_DELTA_2G];
222 
223 	if (!(val & MT_EE_RATE_DELTA_EN))
224 		return 0;
225 
226 	delta = FIELD_GET(MT_EE_RATE_DELTA_MASK, val);
227 
228 	return val & MT_EE_RATE_DELTA_SIGN ? delta : -delta;
229 }
230