1 // SPDX-License-Identifier: ISC
2 /* Copyright (C) 2019 MediaTek Inc.
4 * Author: Ryder Lee <ryder.lee@mediatek.com>
5 * Felix Fietkau <nbd@nbd.name>
12 static int mt7615_efuse_read(struct mt7615_dev
*dev
, u32 base
,
18 val
= mt76_rr(dev
, base
+ MT_EFUSE_CTRL
);
19 val
&= ~(MT_EFUSE_CTRL_AIN
| MT_EFUSE_CTRL_MODE
);
20 val
|= FIELD_PREP(MT_EFUSE_CTRL_AIN
, addr
& ~0xf);
21 val
|= MT_EFUSE_CTRL_KICK
;
22 mt76_wr(dev
, base
+ MT_EFUSE_CTRL
, val
);
24 if (!mt76_poll(dev
, base
+ MT_EFUSE_CTRL
, MT_EFUSE_CTRL_KICK
, 0, 1000))
29 val
= mt76_rr(dev
, base
+ MT_EFUSE_CTRL
);
30 if ((val
& MT_EFUSE_CTRL_AOUT
) == MT_EFUSE_CTRL_AOUT
||
31 WARN_ON_ONCE(!(val
& MT_EFUSE_CTRL_VALID
))) {
32 memset(data
, 0x0, 16);
36 for (i
= 0; i
< 4; i
++) {
37 val
= mt76_rr(dev
, base
+ MT_EFUSE_RDATA(i
));
38 put_unaligned_le32(val
, data
+ 4 * i
);
44 static int mt7615_efuse_init(struct mt7615_dev
*dev
, u32 base
)
46 int i
, len
= MT7615_EEPROM_SIZE
;
50 if (is_mt7663(&dev
->mt76
))
51 len
= MT7663_EEPROM_SIZE
;
53 val
= mt76_rr(dev
, base
+ MT_EFUSE_BASE_CTRL
);
54 if (val
& MT_EFUSE_BASE_CTRL_EMPTY
)
57 dev
->mt76
.otp
.data
= devm_kzalloc(dev
->mt76
.dev
, len
, GFP_KERNEL
);
58 dev
->mt76
.otp
.size
= len
;
59 if (!dev
->mt76
.otp
.data
)
62 buf
= dev
->mt76
.otp
.data
;
63 for (i
= 0; i
+ 16 <= len
; i
+= 16) {
66 ret
= mt7615_efuse_read(dev
, base
, i
, buf
+ i
);
74 static int mt7615_eeprom_load(struct mt7615_dev
*dev
, u32 addr
)
78 BUILD_BUG_ON(MT7615_EEPROM_FULL_SIZE
< MT7663_EEPROM_SIZE
);
80 ret
= mt76_eeprom_init(&dev
->mt76
, MT7615_EEPROM_FULL_SIZE
);
84 return mt7615_efuse_init(dev
, addr
);
87 static int mt7615_check_eeprom(struct mt76_dev
*dev
)
89 u16 val
= get_unaligned_le16(dev
->eeprom
.data
);
102 mt7615_eeprom_parse_hw_band_cap(struct mt7615_dev
*dev
)
104 u8 val
, *eeprom
= dev
->mt76
.eeprom
.data
;
106 if (is_mt7663(&dev
->mt76
)) {
108 dev
->mphy
.cap
.has_2ghz
= true;
109 dev
->mphy
.cap
.has_5ghz
= true;
113 if (is_mt7622(&dev
->mt76
)) {
115 dev
->mphy
.cap
.has_2ghz
= true;
119 if (is_mt7611(&dev
->mt76
)) {
121 dev
->mphy
.cap
.has_5ghz
= true;
125 val
= FIELD_GET(MT_EE_NIC_WIFI_CONF_BAND_SEL
,
126 eeprom
[MT_EE_WIFI_CONF
]);
129 dev
->mphy
.cap
.has_5ghz
= true;
132 dev
->dbdc_support
= true;
135 dev
->mphy
.cap
.has_2ghz
= true;
138 dev
->mphy
.cap
.has_2ghz
= true;
139 dev
->mphy
.cap
.has_5ghz
= true;
144 static void mt7615_eeprom_parse_hw_cap(struct mt7615_dev
*dev
)
146 u8
*eeprom
= dev
->mt76
.eeprom
.data
;
149 mt7615_eeprom_parse_hw_band_cap(dev
);
151 if (is_mt7663(&dev
->mt76
)) {
153 tx_mask
= FIELD_GET(MT_EE_HW_CONF1_TX_MASK
,
154 eeprom
[MT7663_EE_HW_CONF1
]);
158 /* read tx-rx mask from eeprom */
159 val
= mt76_rr(dev
, MT_TOP_STRAP_STA
);
160 max_nss
= val
& MT_TOP_3NSS
? 3 : 4;
162 tx_mask
= FIELD_GET(MT_EE_NIC_CONF_TX_MASK
,
163 eeprom
[MT_EE_NIC_CONF_0
]);
165 if (!tx_mask
|| tx_mask
> max_nss
)
168 dev
->chainmask
= BIT(tx_mask
) - 1;
169 dev
->mphy
.antenna_mask
= dev
->chainmask
;
170 dev
->mphy
.chainmask
= dev
->chainmask
;
173 static int mt7663_eeprom_get_target_power_index(struct mt7615_dev
*dev
,
174 struct ieee80211_channel
*chan
,
182 if (chan
->band
== NL80211_BAND_2GHZ
)
183 return MT7663_EE_TX0_2G_TARGET_POWER
+ (chain_idx
<< 4);
185 group
= mt7615_get_channel_group(chan
->hw_value
);
187 index
= MT7663_EE_TX1_5G_G0_TARGET_POWER
;
189 index
= MT7663_EE_TX0_5G_G0_TARGET_POWER
;
191 return index
+ group
* 3;
194 int mt7615_eeprom_get_target_power_index(struct mt7615_dev
*dev
,
195 struct ieee80211_channel
*chan
,
200 if (is_mt7663(&dev
->mt76
))
201 return mt7663_eeprom_get_target_power_index(dev
, chan
,
208 if (mt7615_ext_pa_enabled(dev
, chan
->band
)) {
209 if (chan
->band
== NL80211_BAND_2GHZ
)
210 return MT_EE_EXT_PA_2G_TARGET_POWER
;
212 return MT_EE_EXT_PA_5G_TARGET_POWER
;
216 if (chan
->band
== NL80211_BAND_2GHZ
) {
217 index
= MT_EE_TX0_2G_TARGET_POWER
+ chain_idx
* 6;
219 int group
= mt7615_get_channel_group(chan
->hw_value
);
223 index
= MT_EE_TX1_5G_G0_TARGET_POWER
;
226 index
= MT_EE_TX2_5G_G0_TARGET_POWER
;
229 index
= MT_EE_TX3_5G_G0_TARGET_POWER
;
233 index
= MT_EE_TX0_5G_G0_TARGET_POWER
;
242 int mt7615_eeprom_get_power_delta_index(struct mt7615_dev
*dev
,
243 enum nl80211_band band
)
245 /* assume the first rate has the highest power offset */
246 if (is_mt7663(&dev
->mt76
)) {
247 if (band
== NL80211_BAND_2GHZ
)
248 return MT_EE_TX0_5G_G0_TARGET_POWER
;
250 return MT7663_EE_5G_RATE_POWER
;
253 if (band
== NL80211_BAND_2GHZ
)
254 return MT_EE_2G_RATE_POWER
;
256 return MT_EE_5G_RATE_POWER
;
259 static void mt7615_apply_cal_free_data(struct mt7615_dev
*dev
)
261 static const u16 ical
[] = {
262 0x53, 0x54, 0x55, 0x56, 0x57, 0x5c, 0x5d, 0x62, 0x63, 0x68,
263 0x69, 0x6e, 0x6f, 0x73, 0x74, 0x78, 0x79, 0x82, 0x83, 0x87,
264 0x88, 0x8c, 0x8d, 0x91, 0x92, 0x96, 0x97, 0x9b, 0x9c, 0xa0,
265 0xa1, 0xaa, 0xab, 0xaf, 0xb0, 0xb4, 0xb5, 0xb9, 0xba, 0xf4,
267 0x140, 0x141, 0x145, 0x146, 0x14a, 0x14b, 0x154, 0x155, 0x159,
268 0x15a, 0x15e, 0x15f, 0x163, 0x164, 0x168, 0x169, 0x16d, 0x16e,
269 0x172, 0x173, 0x17c, 0x17d, 0x181, 0x182, 0x186, 0x187, 0x18b,
272 static const u16 ical_nocheck
[] = {
273 0x110, 0x111, 0x112, 0x113, 0x114, 0x115, 0x116, 0x117, 0x118,
274 0x1b5, 0x1b6, 0x1b7, 0x3ac, 0x3ad, 0x3ae, 0x3af, 0x3b0, 0x3b1,
277 u8
*eeprom
= dev
->mt76
.eeprom
.data
;
278 u8
*otp
= dev
->mt76
.otp
.data
;
284 for (i
= 0; i
< ARRAY_SIZE(ical
); i
++)
288 for (i
= 0; i
< ARRAY_SIZE(ical
); i
++)
289 eeprom
[ical
[i
]] = otp
[ical
[i
]];
291 for (i
= 0; i
< ARRAY_SIZE(ical_nocheck
); i
++)
292 eeprom
[ical_nocheck
[i
]] = otp
[ical_nocheck
[i
]];
295 static void mt7622_apply_cal_free_data(struct mt7615_dev
*dev
)
297 static const u16 ical
[] = {
298 0x53, 0x54, 0x55, 0x56, 0xf4, 0xf7, 0x144, 0x156, 0x15b
300 u8
*eeprom
= dev
->mt76
.eeprom
.data
;
301 u8
*otp
= dev
->mt76
.otp
.data
;
307 for (i
= 0; i
< ARRAY_SIZE(ical
); i
++) {
311 eeprom
[ical
[i
]] = otp
[ical
[i
]];
315 static void mt7615_cal_free_data(struct mt7615_dev
*dev
)
317 struct device_node
*np
= dev
->mt76
.dev
->of_node
;
319 if (!np
|| !of_property_read_bool(np
, "mediatek,eeprom-merge-otp"))
322 switch (mt76_chip(&dev
->mt76
)) {
324 mt7622_apply_cal_free_data(dev
);
328 mt7615_apply_cal_free_data(dev
);
333 int mt7615_eeprom_init(struct mt7615_dev
*dev
, u32 addr
)
337 ret
= mt7615_eeprom_load(dev
, addr
);
341 ret
= mt7615_check_eeprom(&dev
->mt76
);
342 if (ret
&& dev
->mt76
.otp
.data
) {
343 memcpy(dev
->mt76
.eeprom
.data
, dev
->mt76
.otp
.data
,
346 dev
->flash_eeprom
= true;
347 mt7615_cal_free_data(dev
);
350 mt7615_eeprom_parse_hw_cap(dev
);
351 memcpy(dev
->mphy
.macaddr
, dev
->mt76
.eeprom
.data
+ MT_EE_MAC_ADDR
,
354 mt76_eeprom_override(&dev
->mphy
);
358 EXPORT_SYMBOL_GPL(mt7615_eeprom_init
);