1 // SPDX-License-Identifier: ISC
3 * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
6 #include <linux/module.h>
7 #include <asm/unaligned.h>
11 #define EE_FIELD(_name, _value) [MT_EE_##_name] = (_value) | 1
14 mt76x2_eeprom_get_macaddr(struct mt76x02_dev
*dev
)
16 void *src
= dev
->mt76
.eeprom
.data
+ MT_EE_MAC_ADDR
;
18 memcpy(dev
->mt76
.macaddr
, src
, ETH_ALEN
);
23 mt76x2_has_cal_free_data(struct mt76x02_dev
*dev
, u8
*efuse
)
25 u16
*efuse_w
= (u16
*)efuse
;
27 if (efuse_w
[MT_EE_NIC_CONF_0
] != 0)
30 if (efuse_w
[MT_EE_XTAL_TRIM_1
] == 0xffff)
33 if (efuse_w
[MT_EE_TX_POWER_DELTA_BW40
] != 0)
36 if (efuse_w
[MT_EE_TX_POWER_0_START_2G
] == 0xffff)
39 if (efuse_w
[MT_EE_TX_POWER_0_GRP3_TX_POWER_DELTA
] != 0)
42 if (efuse_w
[MT_EE_TX_POWER_0_GRP4_TSSI_SLOPE
] == 0xffff)
49 mt76x2_apply_cal_free_data(struct mt76x02_dev
*dev
, u8
*efuse
)
51 #define GROUP_5G(_id) \
52 MT_EE_TX_POWER_0_START_5G + MT_TX_POWER_GROUP_SIZE_5G * (_id), \
53 MT_EE_TX_POWER_0_START_5G + MT_TX_POWER_GROUP_SIZE_5G * (_id) + 1, \
54 MT_EE_TX_POWER_1_START_5G + MT_TX_POWER_GROUP_SIZE_5G * (_id), \
55 MT_EE_TX_POWER_1_START_5G + MT_TX_POWER_GROUP_SIZE_5G * (_id) + 1
57 static const u8 cal_free_bytes
[] = {
59 MT_EE_TX_POWER_EXT_PA_5G
+ 1,
60 MT_EE_TX_POWER_0_START_2G
,
61 MT_EE_TX_POWER_0_START_2G
+ 1,
62 MT_EE_TX_POWER_1_START_2G
,
63 MT_EE_TX_POWER_1_START_2G
+ 1,
70 MT_EE_RF_2G_TSSI_OFF_TXPOWER
,
71 MT_EE_RF_2G_RX_HIGH_GAIN
+ 1,
72 MT_EE_RF_5G_GRP0_1_RX_HIGH_GAIN
,
73 MT_EE_RF_5G_GRP0_1_RX_HIGH_GAIN
+ 1,
74 MT_EE_RF_5G_GRP2_3_RX_HIGH_GAIN
,
75 MT_EE_RF_5G_GRP2_3_RX_HIGH_GAIN
+ 1,
76 MT_EE_RF_5G_GRP4_5_RX_HIGH_GAIN
,
77 MT_EE_RF_5G_GRP4_5_RX_HIGH_GAIN
+ 1,
79 u8
*eeprom
= dev
->mt76
.eeprom
.data
;
81 eeprom
[MT_EE_TX_POWER_0_START_5G
],
82 eeprom
[MT_EE_TX_POWER_0_START_5G
+ 1],
83 eeprom
[MT_EE_TX_POWER_1_START_5G
],
84 eeprom
[MT_EE_TX_POWER_1_START_5G
+ 1]
89 if (!mt76x2_has_cal_free_data(dev
, efuse
))
92 for (i
= 0; i
< ARRAY_SIZE(cal_free_bytes
); i
++) {
93 int offset
= cal_free_bytes
[i
];
95 eeprom
[offset
] = efuse
[offset
];
98 if (!(efuse
[MT_EE_TX_POWER_0_START_5G
] |
99 efuse
[MT_EE_TX_POWER_0_START_5G
+ 1]))
100 memcpy(eeprom
+ MT_EE_TX_POWER_0_START_5G
, prev_grp0
, 2);
101 if (!(efuse
[MT_EE_TX_POWER_1_START_5G
] |
102 efuse
[MT_EE_TX_POWER_1_START_5G
+ 1]))
103 memcpy(eeprom
+ MT_EE_TX_POWER_1_START_5G
, prev_grp0
+ 2, 2);
105 val
= get_unaligned_le16(efuse
+ MT_EE_BT_RCAL_RESULT
);
107 eeprom
[MT_EE_BT_RCAL_RESULT
] = val
& 0xff;
109 val
= get_unaligned_le16(efuse
+ MT_EE_BT_VCDL_CALIBRATION
);
111 eeprom
[MT_EE_BT_VCDL_CALIBRATION
+ 1] = val
>> 8;
113 val
= get_unaligned_le16(efuse
+ MT_EE_BT_PMUCFG
);
115 eeprom
[MT_EE_BT_PMUCFG
] = val
& 0xff;
118 static int mt76x2_check_eeprom(struct mt76x02_dev
*dev
)
120 u16 val
= get_unaligned_le16(dev
->mt76
.eeprom
.data
);
123 val
= get_unaligned_le16(dev
->mt76
.eeprom
.data
+ MT_EE_PCI_ID
);
130 dev_err(dev
->mt76
.dev
, "EEPROM data check failed: %04x\n", val
);
136 mt76x2_eeprom_load(struct mt76x02_dev
*dev
)
142 ret
= mt76_eeprom_init(&dev
->mt76
, MT7662_EEPROM_SIZE
);
148 found
= !mt76x2_check_eeprom(dev
);
150 dev
->mt76
.otp
.data
= devm_kzalloc(dev
->mt76
.dev
, MT7662_EEPROM_SIZE
,
152 dev
->mt76
.otp
.size
= MT7662_EEPROM_SIZE
;
153 if (!dev
->mt76
.otp
.data
)
156 efuse
= dev
->mt76
.otp
.data
;
158 if (mt76x02_get_efuse_data(dev
, 0, efuse
, MT7662_EEPROM_SIZE
,
163 mt76x2_apply_cal_free_data(dev
, efuse
);
165 /* FIXME: check if efuse data is complete */
167 memcpy(dev
->mt76
.eeprom
.data
, efuse
, MT7662_EEPROM_SIZE
);
178 mt76x2_set_rx_gain_group(struct mt76x02_dev
*dev
, u8 val
)
180 s8
*dest
= dev
->cal
.rx
.high_gain
;
182 if (!mt76x02_field_valid(val
)) {
188 dest
[0] = mt76x02_sign_extend(val
, 4);
189 dest
[1] = mt76x02_sign_extend(val
>> 4, 4);
193 mt76x2_set_rssi_offset(struct mt76x02_dev
*dev
, int chain
, u8 val
)
195 s8
*dest
= dev
->cal
.rx
.rssi_offset
;
197 if (!mt76x02_field_valid(val
)) {
202 dest
[chain
] = mt76x02_sign_extend_optional(val
, 7);
205 static enum mt76x2_cal_channel_group
206 mt76x2_get_cal_channel_group(int channel
)
208 if (channel
>= 184 && channel
<= 196)
209 return MT_CH_5G_JAPAN
;
211 return MT_CH_5G_UNII_1
;
213 return MT_CH_5G_UNII_2
;
215 return MT_CH_5G_UNII_2E_1
;
217 return MT_CH_5G_UNII_2E_2
;
218 return MT_CH_5G_UNII_3
;
222 mt76x2_get_5g_rx_gain(struct mt76x02_dev
*dev
, u8 channel
)
224 enum mt76x2_cal_channel_group group
;
226 group
= mt76x2_get_cal_channel_group(channel
);
229 return mt76x02_eeprom_get(dev
,
230 MT_EE_RF_5G_GRP0_1_RX_HIGH_GAIN
);
231 case MT_CH_5G_UNII_1
:
232 return mt76x02_eeprom_get(dev
,
233 MT_EE_RF_5G_GRP0_1_RX_HIGH_GAIN
) >> 8;
234 case MT_CH_5G_UNII_2
:
235 return mt76x02_eeprom_get(dev
,
236 MT_EE_RF_5G_GRP2_3_RX_HIGH_GAIN
);
237 case MT_CH_5G_UNII_2E_1
:
238 return mt76x02_eeprom_get(dev
,
239 MT_EE_RF_5G_GRP2_3_RX_HIGH_GAIN
) >> 8;
240 case MT_CH_5G_UNII_2E_2
:
241 return mt76x02_eeprom_get(dev
,
242 MT_EE_RF_5G_GRP4_5_RX_HIGH_GAIN
);
244 return mt76x02_eeprom_get(dev
,
245 MT_EE_RF_5G_GRP4_5_RX_HIGH_GAIN
) >> 8;
249 void mt76x2_read_rx_gain(struct mt76x02_dev
*dev
)
251 struct ieee80211_channel
*chan
= dev
->mt76
.chandef
.chan
;
252 int channel
= chan
->hw_value
;
253 s8 lna_5g
[3], lna_2g
;
257 if (chan
->band
== NL80211_BAND_2GHZ
)
258 val
= mt76x02_eeprom_get(dev
, MT_EE_RF_2G_RX_HIGH_GAIN
) >> 8;
260 val
= mt76x2_get_5g_rx_gain(dev
, channel
);
262 mt76x2_set_rx_gain_group(dev
, val
);
264 mt76x02_get_rx_gain(dev
, chan
->band
, &val
, &lna_2g
, lna_5g
);
265 mt76x2_set_rssi_offset(dev
, 0, val
);
266 mt76x2_set_rssi_offset(dev
, 1, val
>> 8);
268 dev
->cal
.rx
.mcu_gain
= (lna_2g
& 0xff);
269 dev
->cal
.rx
.mcu_gain
|= (lna_5g
[0] & 0xff) << 8;
270 dev
->cal
.rx
.mcu_gain
|= (lna_5g
[1] & 0xff) << 16;
271 dev
->cal
.rx
.mcu_gain
|= (lna_5g
[2] & 0xff) << 24;
273 lna
= mt76x02_get_lna_gain(dev
, &lna_2g
, lna_5g
, chan
);
274 dev
->cal
.rx
.lna_gain
= mt76x02_sign_extend(lna
, 8);
276 EXPORT_SYMBOL_GPL(mt76x2_read_rx_gain
);
278 void mt76x2_get_rate_power(struct mt76x02_dev
*dev
, struct mt76_rate_power
*t
,
279 struct ieee80211_channel
*chan
)
284 is_5ghz
= chan
->band
== NL80211_BAND_5GHZ
;
286 memset(t
, 0, sizeof(*t
));
288 val
= mt76x02_eeprom_get(dev
, MT_EE_TX_POWER_CCK
);
289 t
->cck
[0] = t
->cck
[1] = mt76x02_rate_power_val(val
);
290 t
->cck
[2] = t
->cck
[3] = mt76x02_rate_power_val(val
>> 8);
293 val
= mt76x02_eeprom_get(dev
, MT_EE_TX_POWER_OFDM_5G_6M
);
295 val
= mt76x02_eeprom_get(dev
, MT_EE_TX_POWER_OFDM_2G_6M
);
296 t
->ofdm
[0] = t
->ofdm
[1] = mt76x02_rate_power_val(val
);
297 t
->ofdm
[2] = t
->ofdm
[3] = mt76x02_rate_power_val(val
>> 8);
300 val
= mt76x02_eeprom_get(dev
, MT_EE_TX_POWER_OFDM_5G_24M
);
302 val
= mt76x02_eeprom_get(dev
, MT_EE_TX_POWER_OFDM_2G_24M
);
303 t
->ofdm
[4] = t
->ofdm
[5] = mt76x02_rate_power_val(val
);
304 t
->ofdm
[6] = t
->ofdm
[7] = mt76x02_rate_power_val(val
>> 8);
306 val
= mt76x02_eeprom_get(dev
, MT_EE_TX_POWER_HT_MCS0
);
307 t
->ht
[0] = t
->ht
[1] = mt76x02_rate_power_val(val
);
308 t
->ht
[2] = t
->ht
[3] = mt76x02_rate_power_val(val
>> 8);
310 val
= mt76x02_eeprom_get(dev
, MT_EE_TX_POWER_HT_MCS4
);
311 t
->ht
[4] = t
->ht
[5] = mt76x02_rate_power_val(val
);
312 t
->ht
[6] = t
->ht
[7] = mt76x02_rate_power_val(val
>> 8);
314 val
= mt76x02_eeprom_get(dev
, MT_EE_TX_POWER_HT_MCS8
);
315 t
->ht
[8] = t
->ht
[9] = mt76x02_rate_power_val(val
);
316 t
->ht
[10] = t
->ht
[11] = mt76x02_rate_power_val(val
>> 8);
318 val
= mt76x02_eeprom_get(dev
, MT_EE_TX_POWER_HT_MCS12
);
319 t
->ht
[12] = t
->ht
[13] = mt76x02_rate_power_val(val
);
320 t
->ht
[14] = t
->ht
[15] = mt76x02_rate_power_val(val
>> 8);
322 val
= mt76x02_eeprom_get(dev
, MT_EE_TX_POWER_VHT_MCS0
);
323 t
->vht
[0] = t
->vht
[1] = mt76x02_rate_power_val(val
);
324 t
->vht
[2] = t
->vht
[3] = mt76x02_rate_power_val(val
>> 8);
326 val
= mt76x02_eeprom_get(dev
, MT_EE_TX_POWER_VHT_MCS4
);
327 t
->vht
[4] = t
->vht
[5] = mt76x02_rate_power_val(val
);
328 t
->vht
[6] = t
->vht
[7] = mt76x02_rate_power_val(val
>> 8);
330 val
= mt76x02_eeprom_get(dev
, MT_EE_TX_POWER_VHT_MCS8
);
333 t
->vht
[8] = t
->vht
[9] = mt76x02_rate_power_val(val
>> 8);
335 memcpy(t
->stbc
, t
->ht
, sizeof(t
->stbc
[0]) * 8);
336 t
->stbc
[8] = t
->vht
[8];
337 t
->stbc
[9] = t
->vht
[9];
339 EXPORT_SYMBOL_GPL(mt76x2_get_rate_power
);
342 mt76x2_get_power_info_2g(struct mt76x02_dev
*dev
,
343 struct mt76x2_tx_power_info
*t
,
344 struct ieee80211_channel
*chan
,
345 int chain
, int offset
)
347 int channel
= chan
->hw_value
;
354 else if (channel
< 11)
359 mt76x02_eeprom_copy(dev
, offset
, data
, sizeof(data
));
361 t
->chain
[chain
].tssi_slope
= data
[0];
362 t
->chain
[chain
].tssi_offset
= data
[1];
363 t
->chain
[chain
].target_power
= data
[2];
364 t
->chain
[chain
].delta
=
365 mt76x02_sign_extend_optional(data
[delta_idx
], 7);
367 val
= mt76x02_eeprom_get(dev
, MT_EE_RF_2G_TSSI_OFF_TXPOWER
);
368 t
->target_power
= val
>> 8;
372 mt76x2_get_power_info_5g(struct mt76x02_dev
*dev
,
373 struct mt76x2_tx_power_info
*t
,
374 struct ieee80211_channel
*chan
,
375 int chain
, int offset
)
377 int channel
= chan
->hw_value
;
378 enum mt76x2_cal_channel_group group
;
383 group
= mt76x2_get_cal_channel_group(channel
);
384 offset
+= group
* MT_TX_POWER_GROUP_SIZE_5G
;
388 else if (channel
>= 184)
390 else if (channel
< 44)
392 else if (channel
< 52)
394 else if (channel
< 58)
396 else if (channel
< 98)
398 else if (channel
< 106)
400 else if (channel
< 116)
402 else if (channel
< 130)
404 else if (channel
< 149)
406 else if (channel
< 157)
411 mt76x02_eeprom_copy(dev
, offset
, data
, sizeof(data
));
413 t
->chain
[chain
].tssi_slope
= data
[0];
414 t
->chain
[chain
].tssi_offset
= data
[1];
415 t
->chain
[chain
].target_power
= data
[2];
416 t
->chain
[chain
].delta
=
417 mt76x02_sign_extend_optional(data
[delta_idx
], 7);
419 val
= mt76x02_eeprom_get(dev
, MT_EE_RF_2G_RX_HIGH_GAIN
);
420 t
->target_power
= val
& 0xff;
423 void mt76x2_get_power_info(struct mt76x02_dev
*dev
,
424 struct mt76x2_tx_power_info
*t
,
425 struct ieee80211_channel
*chan
)
429 memset(t
, 0, sizeof(*t
));
431 bw40
= mt76x02_eeprom_get(dev
, MT_EE_TX_POWER_DELTA_BW40
);
432 bw80
= mt76x02_eeprom_get(dev
, MT_EE_TX_POWER_DELTA_BW80
);
434 if (chan
->band
== NL80211_BAND_5GHZ
) {
436 mt76x2_get_power_info_5g(dev
, t
, chan
, 0,
437 MT_EE_TX_POWER_0_START_5G
);
438 mt76x2_get_power_info_5g(dev
, t
, chan
, 1,
439 MT_EE_TX_POWER_1_START_5G
);
441 mt76x2_get_power_info_2g(dev
, t
, chan
, 0,
442 MT_EE_TX_POWER_0_START_2G
);
443 mt76x2_get_power_info_2g(dev
, t
, chan
, 1,
444 MT_EE_TX_POWER_1_START_2G
);
447 if (mt76x2_tssi_enabled(dev
) ||
448 !mt76x02_field_valid(t
->target_power
))
449 t
->target_power
= t
->chain
[0].target_power
;
451 t
->delta_bw40
= mt76x02_rate_power_val(bw40
);
452 t
->delta_bw80
= mt76x02_rate_power_val(bw80
);
454 EXPORT_SYMBOL_GPL(mt76x2_get_power_info
);
456 int mt76x2_get_temp_comp(struct mt76x02_dev
*dev
, struct mt76x2_temp_comp
*t
)
458 enum nl80211_band band
= dev
->mt76
.chandef
.chan
->band
;
462 memset(t
, 0, sizeof(*t
));
464 if (!mt76x2_temp_tx_alc_enabled(dev
))
467 if (!mt76x02_ext_pa_enabled(dev
, band
))
470 val
= mt76x02_eeprom_get(dev
, MT_EE_TX_POWER_EXT_PA_5G
) >> 8;
471 t
->temp_25_ref
= val
& 0x7f;
472 if (band
== NL80211_BAND_5GHZ
) {
473 slope
= mt76x02_eeprom_get(dev
, MT_EE_RF_TEMP_COMP_SLOPE_5G
);
474 bounds
= mt76x02_eeprom_get(dev
, MT_EE_TX_POWER_EXT_PA_5G
);
476 slope
= mt76x02_eeprom_get(dev
, MT_EE_RF_TEMP_COMP_SLOPE_2G
);
477 bounds
= mt76x02_eeprom_get(dev
,
478 MT_EE_TX_POWER_DELTA_BW80
) >> 8;
481 t
->high_slope
= slope
& 0xff;
482 t
->low_slope
= slope
>> 8;
483 t
->lower_bound
= 0 - (bounds
& 0xf);
484 t
->upper_bound
= (bounds
>> 4) & 0xf;
488 EXPORT_SYMBOL_GPL(mt76x2_get_temp_comp
);
490 int mt76x2_eeprom_init(struct mt76x02_dev
*dev
)
494 ret
= mt76x2_eeprom_load(dev
);
498 mt76x02_eeprom_parse_hw_cap(dev
);
499 mt76x2_eeprom_get_macaddr(dev
);
500 mt76_eeprom_override(&dev
->mt76
);
501 dev
->mt76
.macaddr
[0] &= ~BIT(1);
505 EXPORT_SYMBOL_GPL(mt76x2_eeprom_init
);
507 MODULE_LICENSE("Dual BSD/GPL");