1 // SPDX-License-Identifier: ISC
3 * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
4 * Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
7 #include <asm/unaligned.h>
9 #include "mt76x02_eeprom.h"
12 mt76x02_efuse_read(struct mt76x02_dev
*dev
, u16 addr
, u8
*data
,
13 enum mt76x02_eeprom_modes mode
)
18 val
= mt76_rr(dev
, MT_EFUSE_CTRL
);
19 val
&= ~(MT_EFUSE_CTRL_AIN
|
21 val
|= FIELD_PREP(MT_EFUSE_CTRL_AIN
, addr
& ~0xf);
22 val
|= FIELD_PREP(MT_EFUSE_CTRL_MODE
, mode
);
23 val
|= MT_EFUSE_CTRL_KICK
;
24 mt76_wr(dev
, MT_EFUSE_CTRL
, val
);
26 if (!mt76_poll_msec(dev
, MT_EFUSE_CTRL
, MT_EFUSE_CTRL_KICK
, 0, 1000))
31 val
= mt76_rr(dev
, MT_EFUSE_CTRL
);
32 if ((val
& MT_EFUSE_CTRL_AOUT
) == MT_EFUSE_CTRL_AOUT
) {
33 memset(data
, 0xff, 16);
37 for (i
= 0; i
< 4; i
++) {
38 val
= mt76_rr(dev
, MT_EFUSE_DATA(i
));
39 put_unaligned_le32(val
, data
+ 4 * i
);
45 int mt76x02_eeprom_copy(struct mt76x02_dev
*dev
,
46 enum mt76x02_eeprom_field field
,
49 if (field
+ len
> dev
->mt76
.eeprom
.size
)
52 memcpy(dest
, dev
->mt76
.eeprom
.data
+ field
, len
);
55 EXPORT_SYMBOL_GPL(mt76x02_eeprom_copy
);
57 int mt76x02_get_efuse_data(struct mt76x02_dev
*dev
, u16 base
, void *buf
,
58 int len
, enum mt76x02_eeprom_modes mode
)
62 for (i
= 0; i
+ 16 <= len
; i
+= 16) {
63 ret
= mt76x02_efuse_read(dev
, base
+ i
, buf
+ i
, mode
);
70 EXPORT_SYMBOL_GPL(mt76x02_get_efuse_data
);
72 void mt76x02_eeprom_parse_hw_cap(struct mt76x02_dev
*dev
)
74 u16 val
= mt76x02_eeprom_get(dev
, MT_EE_NIC_CONF_0
);
76 switch (FIELD_GET(MT_EE_NIC_CONF_0_BOARD_TYPE
, val
)) {
78 dev
->mt76
.cap
.has_5ghz
= true;
81 dev
->mt76
.cap
.has_2ghz
= true;
84 dev
->mt76
.cap
.has_2ghz
= true;
85 dev
->mt76
.cap
.has_5ghz
= true;
89 EXPORT_SYMBOL_GPL(mt76x02_eeprom_parse_hw_cap
);
91 bool mt76x02_ext_pa_enabled(struct mt76x02_dev
*dev
, enum nl80211_band band
)
93 u16 conf0
= mt76x02_eeprom_get(dev
, MT_EE_NIC_CONF_0
);
95 if (band
== NL80211_BAND_5GHZ
)
96 return !(conf0
& MT_EE_NIC_CONF_0_PA_INT_5G
);
98 return !(conf0
& MT_EE_NIC_CONF_0_PA_INT_2G
);
100 EXPORT_SYMBOL_GPL(mt76x02_ext_pa_enabled
);
102 void mt76x02_get_rx_gain(struct mt76x02_dev
*dev
, enum nl80211_band band
,
103 u16
*rssi_offset
, s8
*lna_2g
, s8
*lna_5g
)
107 val
= mt76x02_eeprom_get(dev
, MT_EE_LNA_GAIN
);
108 *lna_2g
= val
& 0xff;
109 lna_5g
[0] = val
>> 8;
111 val
= mt76x02_eeprom_get(dev
, MT_EE_RSSI_OFFSET_2G_1
);
112 lna_5g
[1] = val
>> 8;
114 val
= mt76x02_eeprom_get(dev
, MT_EE_RSSI_OFFSET_5G_1
);
115 lna_5g
[2] = val
>> 8;
117 if (!mt76x02_field_valid(lna_5g
[1]))
118 lna_5g
[1] = lna_5g
[0];
120 if (!mt76x02_field_valid(lna_5g
[2]))
121 lna_5g
[2] = lna_5g
[0];
123 if (band
== NL80211_BAND_2GHZ
)
124 *rssi_offset
= mt76x02_eeprom_get(dev
, MT_EE_RSSI_OFFSET_2G_0
);
126 *rssi_offset
= mt76x02_eeprom_get(dev
, MT_EE_RSSI_OFFSET_5G_0
);
128 EXPORT_SYMBOL_GPL(mt76x02_get_rx_gain
);
130 u8
mt76x02_get_lna_gain(struct mt76x02_dev
*dev
,
131 s8
*lna_2g
, s8
*lna_5g
,
132 struct ieee80211_channel
*chan
)
137 val
= mt76x02_eeprom_get(dev
, MT_EE_NIC_CONF_1
);
138 if (val
& MT_EE_NIC_CONF_1_LNA_EXT_2G
)
140 if (val
& MT_EE_NIC_CONF_1_LNA_EXT_5G
)
141 memset(lna_5g
, 0, sizeof(s8
) * 3);
143 if (chan
->band
== NL80211_BAND_2GHZ
)
145 else if (chan
->hw_value
<= 64)
147 else if (chan
->hw_value
<= 128)
152 return lna
!= 0xff ? lna
: 0;
154 EXPORT_SYMBOL_GPL(mt76x02_get_lna_gain
);