blob: 0c172db0eb92f91ceaa611f12362f4d437f9176e [file] [log] [blame]
developerb11a5392022-03-31 00:34:47 +08001// SPDX-License-Identifier: ISC
2/* Copyright (C) 2020 MediaTek Inc. */
3
4#include <linux/firmware.h>
developer7800b8d2022-06-23 22:15:56 +08005#include "besra.h"
developerb11a5392022-03-31 00:34:47 +08006#include "eeprom.h"
7
developer7800b8d2022-06-23 22:15:56 +08008static int besra_eeprom_load_precal(struct besra_dev *dev)
developerb11a5392022-03-31 00:34:47 +08009{
10 struct mt76_dev *mdev = &dev->mt76;
11 u8 *eeprom = mdev->eeprom.data;
12 u32 val = eeprom[MT_EE_DO_PRE_CAL];
13
14 if (!dev->flash_mode)
15 return 0;
16
17 if (val != (MT_EE_WIFI_CAL_DPD | MT_EE_WIFI_CAL_GROUP))
18 return 0;
19
20 val = MT_EE_CAL_GROUP_SIZE + MT_EE_CAL_DPD_SIZE;
21 dev->cal = devm_kzalloc(mdev->dev, val, GFP_KERNEL);
22 if (!dev->cal)
23 return -ENOMEM;
24
25 return mt76_get_of_eeprom(mdev, dev->cal, MT_EE_PRECAL_V2, val);
26}
27
developer7800b8d2022-06-23 22:15:56 +080028static int besra_check_eeprom(struct besra_dev *dev)
developerb11a5392022-03-31 00:34:47 +080029{
30 u8 *eeprom = dev->mt76.eeprom.data;
31 u16 val = get_unaligned_le16(eeprom);
32
33 switch (val) {
34 case 0x7915:
35 case 0x7916:
36 case 0x7986:
37 return 0;
38 default:
39 return -EINVAL;
40 }
41}
42
developer7800b8d2022-06-23 22:15:56 +080043static char *besra_eeprom_name(struct besra_dev *dev)
developerb11a5392022-03-31 00:34:47 +080044{
45 return MT7902_EEPROM_DEFAULT;
46}
47
48static int
developer7800b8d2022-06-23 22:15:56 +080049besra_eeprom_load_default(struct besra_dev *dev)
developerb11a5392022-03-31 00:34:47 +080050{
51 u8 *eeprom = dev->mt76.eeprom.data;
52 const struct firmware *fw = NULL;
53 int ret;
54
developer7800b8d2022-06-23 22:15:56 +080055 ret = request_firmware(&fw, besra_eeprom_name(dev), dev->mt76.dev);
developerb11a5392022-03-31 00:34:47 +080056 if (ret)
57 return ret;
58
59 if (!fw || !fw->data) {
60 dev_err(dev->mt76.dev, "Invalid default bin\n");
61 ret = -EINVAL;
62 goto out;
63 }
64
developer7800b8d2022-06-23 22:15:56 +080065 memcpy(eeprom, fw->data, BESRA_EEPROM_SIZE);
developerb11a5392022-03-31 00:34:47 +080066 dev->flash_mode = true;
67
68out:
69 release_firmware(fw);
70
71 return ret;
72}
73
developer7800b8d2022-06-23 22:15:56 +080074static int besra_eeprom_load(struct besra_dev *dev)
developerb11a5392022-03-31 00:34:47 +080075{
76 int ret;
77
developer7800b8d2022-06-23 22:15:56 +080078 ret = mt76_eeprom_init(&dev->mt76, BESRA_EEPROM_SIZE);
developerb11a5392022-03-31 00:34:47 +080079 if (ret < 0)
80 return ret;
81
82 if (ret) {
83 dev->flash_mode = true;
84 } else {
85 u8 free_block_num;
86 u32 block_num, i;
87
developer7800b8d2022-06-23 22:15:56 +080088 besra_mcu_get_eeprom_free_block(dev, &free_block_num);
developerb11a5392022-03-31 00:34:47 +080089 /* efuse info not enough */
90 if (free_block_num >= 29)
91 return -EINVAL;
92
93 /* read eeprom data from efuse */
developer7800b8d2022-06-23 22:15:56 +080094 block_num = DIV_ROUND_UP(BESRA_EEPROM_SIZE,
95 BESRA_EEPROM_BLOCK_SIZE);
developerb11a5392022-03-31 00:34:47 +080096 for (i = 0; i < block_num; i++)
developer7800b8d2022-06-23 22:15:56 +080097 besra_mcu_get_eeprom(dev,
98 i * BESRA_EEPROM_BLOCK_SIZE);
developerb11a5392022-03-31 00:34:47 +080099 }
100
developer7800b8d2022-06-23 22:15:56 +0800101 return besra_check_eeprom(dev);
developerb11a5392022-03-31 00:34:47 +0800102}
103
developer7800b8d2022-06-23 22:15:56 +0800104static void besra_eeprom_parse_band_config(struct besra_phy *phy)
developerb11a5392022-03-31 00:34:47 +0800105{
developer7800b8d2022-06-23 22:15:56 +0800106 struct besra_dev *dev = phy->dev;
developerb11a5392022-03-31 00:34:47 +0800107 u8 *eeprom = dev->mt76.eeprom.data;
108 u32 val;
109
110 /* TODO:
111 * since default bin hasn't properly configured yet,
112 * currently hardcode band cap for bellwether */
113
114 /* val = eeprom[MT_EE_WIFI_CONF + phy->band_idx]; */
115 /* val = FIELD_GET(MT_EE_WIFI_CONF0_BAND_SEL, val); */
116
developer66cd2092022-05-10 15:43:01 +0800117 /* switch (val) { */
118 /* case MT_EE_V2_BAND_SEL_5GHZ: */
119 /* phy->mt76->cap.has_5ghz = true; */
120 /* return; */
121 /* case MT_EE_V2_BAND_SEL_6GHZ: */
122 /* phy->mt76->cap.has_6ghz = true; */
123 /* return; */
124 /* case MT_EE_V2_BAND_SEL_5GHZ_6GHZ: */
125 /* phy->mt76->cap.has_5ghz = true; */
126 /* phy->mt76->cap.has_6ghz = true; */
127 /* return; */
128 /* default */
129 /* phy->mt76->cap.has_2ghz = true; */
130 /* return; */
131 /* } */
132
developerb11a5392022-03-31 00:34:47 +0800133 if (phy->band_idx == 2)
134 phy->mt76->cap.has_2ghz = true;
developer66cd2092022-05-10 15:43:01 +0800135 else {
developerb11a5392022-03-31 00:34:47 +0800136 phy->mt76->cap.has_5ghz = true;
developer66cd2092022-05-10 15:43:01 +0800137 /* phy->mt76->cap.has_6ghz = true; */
138 }
developerb11a5392022-03-31 00:34:47 +0800139}
140
developer7800b8d2022-06-23 22:15:56 +0800141void besra_eeprom_parse_hw_cap(struct besra_dev *dev,
142 struct besra_phy *phy)
developerb11a5392022-03-31 00:34:47 +0800143{
144 u8 nss, nss_band, nss_band_max, *eeprom = dev->mt76.eeprom.data;
145 struct mt76_phy *mphy = phy->mt76;
developer7800b8d2022-06-23 22:15:56 +0800146 u8 phy_idx = besra_get_phy_id(phy);
developerb11a5392022-03-31 00:34:47 +0800147
developer7800b8d2022-06-23 22:15:56 +0800148 besra_eeprom_parse_band_config(phy);
developerb11a5392022-03-31 00:34:47 +0800149
150 /* read tx/rx mask from eeprom */
151 nss = FIELD_GET(MT_EE_WIFI_CONF0_TX_PATH,
152 eeprom[MT_EE_WIFI_CONF + phy->band_idx]);
153
154 if (!nss || nss > 4)
155 nss = 4;
156
157 /* read tx/rx stream */
158 nss_band = nss;
159
160 if (dev->dbdc_support) {
161 nss_band = FIELD_GET(MT_EE_WIFI_CONF_STREAM_NUM,
162 eeprom[MT_EE_WIFI_CONF + 2 + phy->band_idx]);
163
164 nss_band_max = MT_EE_NSS_MAX_DBDC_MA7986;
165 } else {
166 nss_band_max = MT_EE_NSS_MAX_MA7986;
167 }
168
169 if (!nss_band || nss_band > nss_band_max)
170 nss_band = nss_band_max;
171
172 if (nss_band > nss) {
173 dev_warn(dev->mt76.dev,
174 "nss mismatch, nss(%d) nss_band(%d) band(%d) phy_id(%d)\n",
175 nss, nss_band, phy->band_idx, phy_idx);
176 nss = nss_band;
177 }
178
179 mphy->chainmask = BIT(nss) - 1;
180 switch (phy_idx) {
181 case MT_MAIN_PHY:
182 dev->chain_shift_ext = hweight8(mphy->chainmask);
183 dev->chain_shift_tri = dev->chain_shift_ext;
184 break;
185 case MT_EXT_PHY:
186 mphy->chainmask <<= dev->chain_shift_ext;
187 dev->chain_shift_tri += hweight8(mphy->chainmask);
188 break;
189 case MT_TRI_PHY:
190 mphy->chainmask <<= dev->chain_shift_tri;
191 break;
192 default:
193 break;
194 }
195 mphy->antenna_mask = BIT(nss_band) - 1;
196 dev->chainmask |= mphy->chainmask;
197
198 dev_err(dev->mt76.dev,
199 "nss info, nss(%d) nss_band(%d) band(%d) phy_id(%d) chainmask(%08x) antenna_mask(%02x) dev chainmask(%08x)\n",
200 nss, nss_band, phy->band_idx, phy_idx,
201 mphy->chainmask, mphy->antenna_mask, dev->chainmask);
202}
203
developer7800b8d2022-06-23 22:15:56 +0800204int besra_eeprom_init(struct besra_dev *dev)
developerb11a5392022-03-31 00:34:47 +0800205{
206 int ret;
207
developer7800b8d2022-06-23 22:15:56 +0800208 ret = besra_eeprom_load(dev);
developerb11a5392022-03-31 00:34:47 +0800209 if (ret < 0) {
210 if (ret != -EINVAL)
211 return ret;
212
213 dev_warn(dev->mt76.dev, "eeprom load fail, use default bin\n");
developer7800b8d2022-06-23 22:15:56 +0800214 ret = besra_eeprom_load_default(dev);
developerb11a5392022-03-31 00:34:47 +0800215 if (ret)
216 return ret;
217 }
218
developer7800b8d2022-06-23 22:15:56 +0800219 ret = besra_eeprom_load_precal(dev);
developerb11a5392022-03-31 00:34:47 +0800220 if (ret)
221 return ret;
222
developer7800b8d2022-06-23 22:15:56 +0800223 besra_eeprom_parse_hw_cap(dev, &dev->phy);
developerb11a5392022-03-31 00:34:47 +0800224 memcpy(dev->mphy.macaddr, dev->mt76.eeprom.data + MT_EE_MAC_ADDR,
225 ETH_ALEN);
226
227 mt76_eeprom_override(&dev->mphy);
228
229 return 0;
230}
231
developer7800b8d2022-06-23 22:15:56 +0800232int besra_eeprom_get_target_power(struct besra_dev *dev,
developerb11a5392022-03-31 00:34:47 +0800233 struct ieee80211_channel *chan,
234 u8 chain_idx)
235{
236 u8 *eeprom = dev->mt76.eeprom.data;
237 int index, target_power;
238 bool tssi_on;
239
240 if (chain_idx > 3)
241 return -EINVAL;
242
developer7800b8d2022-06-23 22:15:56 +0800243 tssi_on = besra_tssi_enabled(dev, chan->band);
developerb11a5392022-03-31 00:34:47 +0800244
245 if (chan->band == NL80211_BAND_2GHZ) {
246 index = MT_EE_TX0_POWER_2G_V2 + chain_idx * 3;
247 target_power = eeprom[index];
248
249 if (!tssi_on)
250 target_power += eeprom[index + 1];
251 } else {
developer7800b8d2022-06-23 22:15:56 +0800252 int group = besra_get_channel_group(chan->hw_value);
developerb11a5392022-03-31 00:34:47 +0800253
254 index = MT_EE_TX0_POWER_5G_V2 + chain_idx * 12;
255 target_power = eeprom[index + group];
256
257 if (!tssi_on)
258 target_power += eeprom[index + 8];
259 }
260
261 return target_power;
262}
263
developer7800b8d2022-06-23 22:15:56 +0800264s8 besra_eeprom_get_power_delta(struct besra_dev *dev, int band)
developerb11a5392022-03-31 00:34:47 +0800265{
266 u8 *eeprom = dev->mt76.eeprom.data;
267 u32 val;
268 s8 delta;
269
270 if (band == NL80211_BAND_2GHZ)
271 val = eeprom[MT_EE_RATE_DELTA_2G_V2];
272 else
273 val = eeprom[MT_EE_RATE_DELTA_5G_V2];
274
275 if (!(val & MT_EE_RATE_DELTA_EN))
276 return 0;
277
278 delta = FIELD_GET(MT_EE_RATE_DELTA_MASK, val);
279
280 return val & MT_EE_RATE_DELTA_SIGN ? delta : -delta;
281}
282
developer7800b8d2022-06-23 22:15:56 +0800283const u8 besra_sku_group_len[] = {
developerb11a5392022-03-31 00:34:47 +0800284 [SKU_CCK] = 4,
285 [SKU_OFDM] = 8,
286 [SKU_HT_BW20] = 8,
287 [SKU_HT_BW40] = 9,
288 [SKU_VHT_BW20] = 12,
289 [SKU_VHT_BW40] = 12,
290 [SKU_VHT_BW80] = 12,
291 [SKU_VHT_BW160] = 12,
292 [SKU_HE_RU26] = 12,
293 [SKU_HE_RU52] = 12,
294 [SKU_HE_RU106] = 12,
295 [SKU_HE_RU242] = 12,
296 [SKU_HE_RU484] = 12,
297 [SKU_HE_RU996] = 12,
298 [SKU_HE_RU2x996] = 12
299};