1 // SPDX-License-Identifier: ISC
3 * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
6 #include <linux/module.h>
8 #include <linux/unaligned.h>
12 #define EE_FIELD(_name, _value) [MT_EE_##_name] = (_value) | 1
15 mt76x2_eeprom_get_macaddr(struct mt76x02_dev
*dev
)
17 void *src
= dev
->mt76
.eeprom
.data
+ MT_EE_MAC_ADDR
;
19 memcpy(dev
->mphy
.macaddr
, src
, ETH_ALEN
);
24 mt76x2_has_cal_free_data(struct mt76x02_dev
*dev
, u8
*efuse
)
26 u16
*efuse_w
= (u16
*)efuse
;
28 if (efuse_w
[MT_EE_NIC_CONF_0
] != 0)
31 if (efuse_w
[MT_EE_XTAL_TRIM_1
] == 0xffff)
34 if (efuse_w
[MT_EE_TX_POWER_DELTA_BW40
] != 0)
37 if (efuse_w
[MT_EE_TX_POWER_0_START_2G
] == 0xffff)
40 if (efuse_w
[MT_EE_TX_POWER_0_GRP3_TX_POWER_DELTA
] != 0)
43 if (efuse_w
[MT_EE_TX_POWER_0_GRP4_TSSI_SLOPE
] == 0xffff)
50 mt76x2_apply_cal_free_data(struct mt76x02_dev
*dev
, u8
*efuse
)
52 #define GROUP_5G(_id) \
53 MT_EE_TX_POWER_0_START_5G + MT_TX_POWER_GROUP_SIZE_5G * (_id), \
54 MT_EE_TX_POWER_0_START_5G + MT_TX_POWER_GROUP_SIZE_5G * (_id) + 1, \
55 MT_EE_TX_POWER_1_START_5G + MT_TX_POWER_GROUP_SIZE_5G * (_id), \
56 MT_EE_TX_POWER_1_START_5G + MT_TX_POWER_GROUP_SIZE_5G * (_id) + 1
58 static const u8 cal_free_bytes
[] = {
60 MT_EE_TX_POWER_EXT_PA_5G
+ 1,
61 MT_EE_TX_POWER_0_START_2G
,
62 MT_EE_TX_POWER_0_START_2G
+ 1,
63 MT_EE_TX_POWER_1_START_2G
,
64 MT_EE_TX_POWER_1_START_2G
+ 1,
71 MT_EE_RF_2G_TSSI_OFF_TXPOWER
,
72 MT_EE_RF_2G_RX_HIGH_GAIN
+ 1,
73 MT_EE_RF_5G_GRP0_1_RX_HIGH_GAIN
,
74 MT_EE_RF_5G_GRP0_1_RX_HIGH_GAIN
+ 1,
75 MT_EE_RF_5G_GRP2_3_RX_HIGH_GAIN
,
76 MT_EE_RF_5G_GRP2_3_RX_HIGH_GAIN
+ 1,
77 MT_EE_RF_5G_GRP4_5_RX_HIGH_GAIN
,
78 MT_EE_RF_5G_GRP4_5_RX_HIGH_GAIN
+ 1,
80 struct device_node
*np
= dev
->mt76
.dev
->of_node
;
81 u8
*eeprom
= dev
->mt76
.eeprom
.data
;
83 eeprom
[MT_EE_TX_POWER_0_START_5G
],
84 eeprom
[MT_EE_TX_POWER_0_START_5G
+ 1],
85 eeprom
[MT_EE_TX_POWER_1_START_5G
],
86 eeprom
[MT_EE_TX_POWER_1_START_5G
+ 1]
91 if (!np
|| !of_property_read_bool(np
, "mediatek,eeprom-merge-otp"))
94 if (!mt76x2_has_cal_free_data(dev
, efuse
))
97 for (i
= 0; i
< ARRAY_SIZE(cal_free_bytes
); i
++) {
98 int offset
= cal_free_bytes
[i
];
100 eeprom
[offset
] = efuse
[offset
];
103 if (!(efuse
[MT_EE_TX_POWER_0_START_5G
] |
104 efuse
[MT_EE_TX_POWER_0_START_5G
+ 1]))
105 memcpy(eeprom
+ MT_EE_TX_POWER_0_START_5G
, prev_grp0
, 2);
106 if (!(efuse
[MT_EE_TX_POWER_1_START_5G
] |
107 efuse
[MT_EE_TX_POWER_1_START_5G
+ 1]))
108 memcpy(eeprom
+ MT_EE_TX_POWER_1_START_5G
, prev_grp0
+ 2, 2);
110 val
= get_unaligned_le16(efuse
+ MT_EE_BT_RCAL_RESULT
);
112 eeprom
[MT_EE_BT_RCAL_RESULT
] = val
& 0xff;
114 val
= get_unaligned_le16(efuse
+ MT_EE_BT_VCDL_CALIBRATION
);
116 eeprom
[MT_EE_BT_VCDL_CALIBRATION
+ 1] = val
>> 8;
118 val
= get_unaligned_le16(efuse
+ MT_EE_BT_PMUCFG
);
120 eeprom
[MT_EE_BT_PMUCFG
] = val
& 0xff;
123 static int mt76x2_check_eeprom(struct mt76x02_dev
*dev
)
125 u16 val
= get_unaligned_le16(dev
->mt76
.eeprom
.data
);
128 val
= get_unaligned_le16(dev
->mt76
.eeprom
.data
+ MT_EE_PCI_ID
);
135 dev_err(dev
->mt76
.dev
, "EEPROM data check failed: %04x\n", val
);
141 mt76x2_eeprom_load(struct mt76x02_dev
*dev
)
147 ret
= mt76_eeprom_init(&dev
->mt76
, MT7662_EEPROM_SIZE
);
153 found
= !mt76x2_check_eeprom(dev
);
155 dev
->mt76
.otp
.data
= devm_kzalloc(dev
->mt76
.dev
, MT7662_EEPROM_SIZE
,
157 dev
->mt76
.otp
.size
= MT7662_EEPROM_SIZE
;
158 if (!dev
->mt76
.otp
.data
)
161 efuse
= dev
->mt76
.otp
.data
;
163 if (mt76x02_get_efuse_data(dev
, 0, efuse
, MT7662_EEPROM_SIZE
,
168 mt76x2_apply_cal_free_data(dev
, efuse
);
170 /* FIXME: check if efuse data is complete */
172 memcpy(dev
->mt76
.eeprom
.data
, efuse
, MT7662_EEPROM_SIZE
);
183 mt76x2_set_rx_gain_group(struct mt76x02_dev
*dev
, u8 val
)
185 s8
*dest
= dev
->cal
.rx
.high_gain
;
187 if (!mt76x02_field_valid(val
)) {
193 dest
[0] = mt76x02_sign_extend(val
, 4);
194 dest
[1] = mt76x02_sign_extend(val
>> 4, 4);
198 mt76x2_set_rssi_offset(struct mt76x02_dev
*dev
, int chain
, u8 val
)
200 s8
*dest
= dev
->cal
.rx
.rssi_offset
;
202 if (!mt76x02_field_valid(val
)) {
207 dest
[chain
] = mt76x02_sign_extend_optional(val
, 7);
210 static enum mt76x2_cal_channel_group
211 mt76x2_get_cal_channel_group(int channel
)
213 if (channel
>= 184 && channel
<= 196)
214 return MT_CH_5G_JAPAN
;
216 return MT_CH_5G_UNII_1
;
218 return MT_CH_5G_UNII_2
;
220 return MT_CH_5G_UNII_2E_1
;
222 return MT_CH_5G_UNII_2E_2
;
223 return MT_CH_5G_UNII_3
;
227 mt76x2_get_5g_rx_gain(struct mt76x02_dev
*dev
, u8 channel
)
229 enum mt76x2_cal_channel_group group
;
231 group
= mt76x2_get_cal_channel_group(channel
);
234 return mt76x02_eeprom_get(dev
,
235 MT_EE_RF_5G_GRP0_1_RX_HIGH_GAIN
);
236 case MT_CH_5G_UNII_1
:
237 return mt76x02_eeprom_get(dev
,
238 MT_EE_RF_5G_GRP0_1_RX_HIGH_GAIN
) >> 8;
239 case MT_CH_5G_UNII_2
:
240 return mt76x02_eeprom_get(dev
,
241 MT_EE_RF_5G_GRP2_3_RX_HIGH_GAIN
);
242 case MT_CH_5G_UNII_2E_1
:
243 return mt76x02_eeprom_get(dev
,
244 MT_EE_RF_5G_GRP2_3_RX_HIGH_GAIN
) >> 8;
245 case MT_CH_5G_UNII_2E_2
:
246 return mt76x02_eeprom_get(dev
,
247 MT_EE_RF_5G_GRP4_5_RX_HIGH_GAIN
);
249 return mt76x02_eeprom_get(dev
,
250 MT_EE_RF_5G_GRP4_5_RX_HIGH_GAIN
) >> 8;
254 void mt76x2_read_rx_gain(struct mt76x02_dev
*dev
)
256 struct ieee80211_channel
*chan
= dev
->mphy
.chandef
.chan
;
257 int channel
= chan
->hw_value
;
258 s8 lna_5g
[3], lna_2g
;
263 if (chan
->band
== NL80211_BAND_2GHZ
)
264 val
= mt76x02_eeprom_get(dev
, MT_EE_RF_2G_RX_HIGH_GAIN
) >> 8;
266 val
= mt76x2_get_5g_rx_gain(dev
, channel
);
268 mt76x2_set_rx_gain_group(dev
, val
);
270 mt76x02_get_rx_gain(dev
, chan
->band
, &val
, &lna_2g
, lna_5g
);
271 mt76x2_set_rssi_offset(dev
, 0, val
);
272 mt76x2_set_rssi_offset(dev
, 1, val
>> 8);
274 dev
->cal
.rx
.mcu_gain
= (lna_2g
& 0xff);
275 dev
->cal
.rx
.mcu_gain
|= (lna_5g
[0] & 0xff) << 8;
276 dev
->cal
.rx
.mcu_gain
|= (lna_5g
[1] & 0xff) << 16;
277 dev
->cal
.rx
.mcu_gain
|= (lna_5g
[2] & 0xff) << 24;
279 val
= mt76x02_eeprom_get(dev
, MT_EE_NIC_CONF_1
);
280 if (chan
->band
== NL80211_BAND_2GHZ
)
281 use_lna
= !(val
& MT_EE_NIC_CONF_1_LNA_EXT_2G
);
283 use_lna
= !(val
& MT_EE_NIC_CONF_1_LNA_EXT_5G
);
286 lna
= mt76x02_get_lna_gain(dev
, &lna_2g
, lna_5g
, chan
);
288 dev
->cal
.rx
.lna_gain
= mt76x02_sign_extend(lna
, 8);
290 EXPORT_SYMBOL_GPL(mt76x2_read_rx_gain
);
292 void mt76x2_get_rate_power(struct mt76x02_dev
*dev
, struct mt76x02_rate_power
*t
,
293 struct ieee80211_channel
*chan
)
298 is_5ghz
= chan
->band
== NL80211_BAND_5GHZ
;
300 memset(t
, 0, sizeof(*t
));
302 val
= mt76x02_eeprom_get(dev
, MT_EE_TX_POWER_CCK
);
303 t
->cck
[0] = t
->cck
[1] = mt76x02_rate_power_val(val
);
304 t
->cck
[2] = t
->cck
[3] = mt76x02_rate_power_val(val
>> 8);
307 val
= mt76x02_eeprom_get(dev
, MT_EE_TX_POWER_OFDM_5G_6M
);
309 val
= mt76x02_eeprom_get(dev
, MT_EE_TX_POWER_OFDM_2G_6M
);
310 t
->ofdm
[0] = t
->ofdm
[1] = mt76x02_rate_power_val(val
);
311 t
->ofdm
[2] = t
->ofdm
[3] = mt76x02_rate_power_val(val
>> 8);
314 val
= mt76x02_eeprom_get(dev
, MT_EE_TX_POWER_OFDM_5G_24M
);
316 val
= mt76x02_eeprom_get(dev
, MT_EE_TX_POWER_OFDM_2G_24M
);
317 t
->ofdm
[4] = t
->ofdm
[5] = mt76x02_rate_power_val(val
);
318 t
->ofdm
[6] = t
->ofdm
[7] = mt76x02_rate_power_val(val
>> 8);
320 val
= mt76x02_eeprom_get(dev
, MT_EE_TX_POWER_HT_MCS0
);
321 t
->ht
[0] = t
->ht
[1] = mt76x02_rate_power_val(val
);
322 t
->ht
[2] = t
->ht
[3] = mt76x02_rate_power_val(val
>> 8);
324 val
= mt76x02_eeprom_get(dev
, MT_EE_TX_POWER_HT_MCS4
);
325 t
->ht
[4] = t
->ht
[5] = mt76x02_rate_power_val(val
);
326 t
->ht
[6] = t
->ht
[7] = mt76x02_rate_power_val(val
>> 8);
328 val
= mt76x02_eeprom_get(dev
, MT_EE_TX_POWER_HT_MCS8
);
329 t
->ht
[8] = t
->ht
[9] = mt76x02_rate_power_val(val
);
330 t
->ht
[10] = t
->ht
[11] = mt76x02_rate_power_val(val
>> 8);
332 val
= mt76x02_eeprom_get(dev
, MT_EE_TX_POWER_HT_MCS12
);
333 t
->ht
[12] = t
->ht
[13] = mt76x02_rate_power_val(val
);
334 t
->ht
[14] = t
->ht
[15] = mt76x02_rate_power_val(val
>> 8);
336 val
= mt76x02_eeprom_get(dev
, MT_EE_TX_POWER_VHT_MCS8
);
339 t
->vht
[0] = t
->vht
[1] = mt76x02_rate_power_val(val
>> 8);
341 EXPORT_SYMBOL_GPL(mt76x2_get_rate_power
);
344 mt76x2_get_power_info_2g(struct mt76x02_dev
*dev
,
345 struct mt76x2_tx_power_info
*t
,
346 struct ieee80211_channel
*chan
,
347 int chain
, int offset
)
349 int channel
= chan
->hw_value
;
356 else if (channel
< 11)
361 mt76x02_eeprom_copy(dev
, offset
, data
, sizeof(data
));
363 t
->chain
[chain
].tssi_slope
= data
[0];
364 t
->chain
[chain
].tssi_offset
= data
[1];
365 t
->chain
[chain
].target_power
= data
[2];
366 t
->chain
[chain
].delta
=
367 mt76x02_sign_extend_optional(data
[delta_idx
], 7);
369 val
= mt76x02_eeprom_get(dev
, MT_EE_RF_2G_TSSI_OFF_TXPOWER
);
370 t
->target_power
= val
>> 8;
374 mt76x2_get_power_info_5g(struct mt76x02_dev
*dev
,
375 struct mt76x2_tx_power_info
*t
,
376 struct ieee80211_channel
*chan
,
377 int chain
, int offset
)
379 int channel
= chan
->hw_value
;
380 enum mt76x2_cal_channel_group group
;
385 group
= mt76x2_get_cal_channel_group(channel
);
386 offset
+= group
* MT_TX_POWER_GROUP_SIZE_5G
;
390 else if (channel
>= 184)
392 else if (channel
< 44)
394 else if (channel
< 52)
396 else if (channel
< 58)
398 else if (channel
< 98)
400 else if (channel
< 106)
402 else if (channel
< 116)
404 else if (channel
< 130)
406 else if (channel
< 149)
408 else if (channel
< 157)
413 mt76x02_eeprom_copy(dev
, offset
, data
, sizeof(data
));
415 t
->chain
[chain
].tssi_slope
= data
[0];
416 t
->chain
[chain
].tssi_offset
= data
[1];
417 t
->chain
[chain
].target_power
= data
[2];
418 t
->chain
[chain
].delta
=
419 mt76x02_sign_extend_optional(data
[delta_idx
], 7);
421 val
= mt76x02_eeprom_get(dev
, MT_EE_RF_2G_RX_HIGH_GAIN
);
422 t
->target_power
= val
& 0xff;
425 void mt76x2_get_power_info(struct mt76x02_dev
*dev
,
426 struct mt76x2_tx_power_info
*t
,
427 struct ieee80211_channel
*chan
)
431 memset(t
, 0, sizeof(*t
));
433 bw40
= mt76x02_eeprom_get(dev
, MT_EE_TX_POWER_DELTA_BW40
);
434 bw80
= mt76x02_eeprom_get(dev
, MT_EE_TX_POWER_DELTA_BW80
);
436 if (chan
->band
== NL80211_BAND_5GHZ
) {
438 mt76x2_get_power_info_5g(dev
, t
, chan
, 0,
439 MT_EE_TX_POWER_0_START_5G
);
440 mt76x2_get_power_info_5g(dev
, t
, chan
, 1,
441 MT_EE_TX_POWER_1_START_5G
);
443 mt76x2_get_power_info_2g(dev
, t
, chan
, 0,
444 MT_EE_TX_POWER_0_START_2G
);
445 mt76x2_get_power_info_2g(dev
, t
, chan
, 1,
446 MT_EE_TX_POWER_1_START_2G
);
449 if (mt76x2_tssi_enabled(dev
) ||
450 !mt76x02_field_valid(t
->target_power
))
451 t
->target_power
= t
->chain
[0].target_power
;
453 t
->delta_bw40
= mt76x02_rate_power_val(bw40
);
454 t
->delta_bw80
= mt76x02_rate_power_val(bw80
);
456 EXPORT_SYMBOL_GPL(mt76x2_get_power_info
);
458 int mt76x2_get_temp_comp(struct mt76x02_dev
*dev
, struct mt76x2_temp_comp
*t
)
460 enum nl80211_band band
= dev
->mphy
.chandef
.chan
->band
;
464 memset(t
, 0, sizeof(*t
));
466 if (!mt76x2_temp_tx_alc_enabled(dev
))
469 if (!mt76x02_ext_pa_enabled(dev
, band
))
472 val
= mt76x02_eeprom_get(dev
, MT_EE_TX_POWER_EXT_PA_5G
) >> 8;
473 t
->temp_25_ref
= val
& 0x7f;
474 if (band
== NL80211_BAND_5GHZ
) {
475 slope
= mt76x02_eeprom_get(dev
, MT_EE_RF_TEMP_COMP_SLOPE_5G
);
476 bounds
= mt76x02_eeprom_get(dev
, MT_EE_TX_POWER_EXT_PA_5G
);
478 slope
= mt76x02_eeprom_get(dev
, MT_EE_RF_TEMP_COMP_SLOPE_2G
);
479 bounds
= mt76x02_eeprom_get(dev
,
480 MT_EE_TX_POWER_DELTA_BW80
) >> 8;
483 t
->high_slope
= slope
& 0xff;
484 t
->low_slope
= slope
>> 8;
485 t
->lower_bound
= 0 - (bounds
& 0xf);
486 t
->upper_bound
= (bounds
>> 4) & 0xf;
490 EXPORT_SYMBOL_GPL(mt76x2_get_temp_comp
);
492 int mt76x2_eeprom_init(struct mt76x02_dev
*dev
)
496 ret
= mt76x2_eeprom_load(dev
);
500 mt76x02_eeprom_parse_hw_cap(dev
);
501 mt76x2_eeprom_get_macaddr(dev
);
502 mt76_eeprom_override(&dev
->mphy
);
503 dev
->mphy
.macaddr
[0] &= ~BIT(1);
507 EXPORT_SYMBOL_GPL(mt76x2_eeprom_init
);
509 MODULE_DESCRIPTION("MediaTek MT76x2 EEPROM helpers");
510 MODULE_LICENSE("Dual BSD/GPL");