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
mt7996_check_eeprom(struct mt7996_dev * dev)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
mt7996_eeprom_name(struct mt7996_dev * dev)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
mt7996_eeprom_load_default(struct mt7996_dev * dev)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
mt7996_eeprom_load(struct mt7996_dev * dev)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 u32 eeprom_blk_size = MT7996_EEPROM_BLOCK_SIZE;
69
70 ret = mt7996_mcu_get_eeprom_free_block(dev, &free_block_num);
71 if (ret < 0)
72 return ret;
73
74 /* efuse info isn't enough */
75 if (free_block_num >= 59)
76 return -EINVAL;
77
78 /* read eeprom data from efuse */
79 block_num = DIV_ROUND_UP(MT7996_EEPROM_SIZE, eeprom_blk_size);
80 for (i = 0; i < block_num; i++) {
81 ret = mt7996_mcu_get_eeprom(dev, i * eeprom_blk_size);
82 if (ret < 0)
83 return ret;
84 }
85 }
86
87 return mt7996_check_eeprom(dev);
88 }
89
mt7996_eeprom_parse_efuse_hw_cap(struct mt7996_dev * dev)90 static int mt7996_eeprom_parse_efuse_hw_cap(struct mt7996_dev *dev)
91 {
92 #define MODE_HE_ONLY BIT(0)
93 #define WTBL_SIZE_GROUP GENMASK(31, 28)
94 u32 cap = 0;
95 int ret;
96
97 ret = mt7996_mcu_get_chip_config(dev, &cap);
98 if (ret)
99 return ret;
100
101 if (cap) {
102 dev->has_eht = !(cap & MODE_HE_ONLY);
103 dev->wtbl_size_group = u32_get_bits(cap, WTBL_SIZE_GROUP);
104 }
105
106 if (dev->wtbl_size_group < 2 || dev->wtbl_size_group > 4)
107 dev->wtbl_size_group = 2; /* set default */
108
109 return 0;
110 }
111
mt7996_eeprom_parse_band_config(struct mt7996_phy * phy)112 static int mt7996_eeprom_parse_band_config(struct mt7996_phy *phy)
113 {
114 u8 *eeprom = phy->dev->mt76.eeprom.data;
115 u32 val = eeprom[MT_EE_WIFI_CONF];
116 int ret = 0;
117
118 switch (phy->mt76->band_idx) {
119 case MT_BAND1:
120 val = FIELD_GET(MT_EE_WIFI_CONF1_BAND_SEL, val);
121 break;
122 case MT_BAND2:
123 val = eeprom[MT_EE_WIFI_CONF + 1];
124 val = FIELD_GET(MT_EE_WIFI_CONF2_BAND_SEL, val);
125 break;
126 default:
127 val = FIELD_GET(MT_EE_WIFI_CONF0_BAND_SEL, val);
128 break;
129 }
130
131 switch (val) {
132 case MT_EE_BAND_SEL_2GHZ:
133 phy->mt76->cap.has_2ghz = true;
134 break;
135 case MT_EE_BAND_SEL_5GHZ:
136 phy->mt76->cap.has_5ghz = true;
137 break;
138 case MT_EE_BAND_SEL_6GHZ:
139 phy->mt76->cap.has_6ghz = true;
140 break;
141 default:
142 ret = -EINVAL;
143 break;
144 }
145
146 return ret;
147 }
148
mt7996_eeprom_parse_hw_cap(struct mt7996_dev * dev,struct mt7996_phy * phy)149 int mt7996_eeprom_parse_hw_cap(struct mt7996_dev *dev, struct mt7996_phy *phy)
150 {
151 u8 path, nss, band_idx = phy->mt76->band_idx;
152 u8 *eeprom = dev->mt76.eeprom.data;
153 struct mt76_phy *mphy = phy->mt76;
154 int ret;
155
156 switch (band_idx) {
157 case MT_BAND1:
158 path = FIELD_GET(MT_EE_WIFI_CONF2_TX_PATH_BAND1,
159 eeprom[MT_EE_WIFI_CONF + 2]);
160 nss = FIELD_GET(MT_EE_WIFI_CONF5_STREAM_NUM_BAND1,
161 eeprom[MT_EE_WIFI_CONF + 5]);
162 break;
163 case MT_BAND2:
164 path = FIELD_GET(MT_EE_WIFI_CONF2_TX_PATH_BAND2,
165 eeprom[MT_EE_WIFI_CONF + 2]);
166 nss = FIELD_GET(MT_EE_WIFI_CONF5_STREAM_NUM_BAND2,
167 eeprom[MT_EE_WIFI_CONF + 5]);
168 break;
169 default:
170 path = FIELD_GET(MT_EE_WIFI_CONF1_TX_PATH_BAND0,
171 eeprom[MT_EE_WIFI_CONF + 1]);
172 nss = FIELD_GET(MT_EE_WIFI_CONF4_STREAM_NUM_BAND0,
173 eeprom[MT_EE_WIFI_CONF + 4]);
174 break;
175 }
176
177 if (!path || path > 4)
178 path = 4;
179
180 nss = min_t(u8, min_t(u8, 4, nss), path);
181
182 mphy->antenna_mask = BIT(nss) - 1;
183 mphy->chainmask = (BIT(path) - 1) << dev->chainshift[band_idx];
184 dev->chainmask |= mphy->chainmask;
185 if (band_idx < MT_BAND2)
186 dev->chainshift[band_idx + 1] = dev->chainshift[band_idx] +
187 hweight16(mphy->chainmask);
188
189 ret = mt7996_eeprom_parse_efuse_hw_cap(dev);
190 if (ret)
191 return ret;
192
193 return mt7996_eeprom_parse_band_config(phy);
194 }
195
mt7996_eeprom_init(struct mt7996_dev * dev)196 int mt7996_eeprom_init(struct mt7996_dev *dev)
197 {
198 int ret;
199
200 ret = mt7996_eeprom_load(dev);
201 if (ret < 0) {
202 if (ret != -EINVAL)
203 return ret;
204
205 dev_warn(dev->mt76.dev, "eeprom load fail, use default bin\n");
206 ret = mt7996_eeprom_load_default(dev);
207 if (ret)
208 return ret;
209 }
210
211 ret = mt7996_eeprom_parse_hw_cap(dev, &dev->phy);
212 if (ret < 0)
213 return ret;
214
215 #if defined(__linux__)
216 memcpy(dev->mphy.macaddr, dev->mt76.eeprom.data + MT_EE_MAC_ADDR, ETH_ALEN);
217 #elif defined(__FreeBSD__)
218 memcpy(dev->mphy.macaddr, (u8 *)dev->mt76.eeprom.data + MT_EE_MAC_ADDR, ETH_ALEN);
219 #endif
220 mt76_eeprom_override(&dev->mphy);
221
222 return 0;
223 }
224
mt7996_eeprom_get_target_power(struct mt7996_dev * dev,struct ieee80211_channel * chan)225 int mt7996_eeprom_get_target_power(struct mt7996_dev *dev,
226 struct ieee80211_channel *chan)
227 {
228 u8 *eeprom = dev->mt76.eeprom.data;
229 int target_power;
230
231 if (chan->band == NL80211_BAND_5GHZ)
232 target_power = eeprom[MT_EE_TX0_POWER_5G +
233 mt7996_get_channel_group_5g(chan->hw_value)];
234 else if (chan->band == NL80211_BAND_6GHZ)
235 target_power = eeprom[MT_EE_TX0_POWER_6G +
236 mt7996_get_channel_group_6g(chan->hw_value)];
237 else
238 target_power = eeprom[MT_EE_TX0_POWER_2G];
239
240 return target_power;
241 }
242
mt7996_eeprom_get_power_delta(struct mt7996_dev * dev,int band)243 s8 mt7996_eeprom_get_power_delta(struct mt7996_dev *dev, int band)
244 {
245 u8 *eeprom = dev->mt76.eeprom.data;
246 u32 val;
247 s8 delta;
248
249 if (band == NL80211_BAND_5GHZ)
250 val = eeprom[MT_EE_RATE_DELTA_5G];
251 else if (band == NL80211_BAND_6GHZ)
252 val = eeprom[MT_EE_RATE_DELTA_6G];
253 else
254 val = eeprom[MT_EE_RATE_DELTA_2G];
255
256 if (!(val & MT_EE_RATE_DELTA_EN))
257 return 0;
258
259 delta = FIELD_GET(MT_EE_RATE_DELTA_MASK, val);
260
261 return val & MT_EE_RATE_DELTA_SIGN ? delta : -delta;
262 }
263