blob: b9f62bedbc4859c5a4d51fb086d83aed69fb2e0d [file] [log] [blame]
developer0f312e82022-11-01 12:31:52 +08001// 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
10static 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
23static char *mt7996_eeprom_name(struct mt7996_dev *dev)
24{
25 /* reserve for future variants */
26 return MT7996_EEPROM_DEFAULT;
27}
28
29static int
30mt7996_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
49out:
50 release_firmware(fw);
51
52 return ret;
53}
54
55static 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
84static 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
125int 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
167int 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
192int 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
210s8 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}