1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (C) 2014 Felix Fietkau <nbd@openwrt.org>
4 * Copyright (C) 2015 Jakub Kicinski <kubakici@wp.pl>
5 * Copyright (C) 2018 Stanislaw Gruszka <stf_xl@wp.pl>
8 #include <linux/module.h>
10 #include <linux/mtd/mtd.h>
11 #include <linux/mtd/partitions.h>
12 #include <linux/etherdevice.h>
13 #include <asm/unaligned.h>
16 #include "../mt76x02_phy.h"
18 #define MT_MAP_READS DIV_ROUND_UP(MT_EFUSE_USAGE_MAP_SIZE, 16)
20 mt76x0_efuse_physical_size_check(struct mt76x02_dev
*dev
)
22 u8 data
[MT_MAP_READS
* 16];
24 u32 start
= 0, end
= 0, cnt_free
;
26 ret
= mt76x02_get_efuse_data(dev
, MT_EE_USAGE_MAP_START
, data
,
27 sizeof(data
), MT_EE_PHYSICAL_READ
);
31 for (i
= 0; i
< MT_EFUSE_USAGE_MAP_SIZE
; i
++)
34 start
= MT_EE_USAGE_MAP_START
+ i
;
35 end
= MT_EE_USAGE_MAP_START
+ i
;
37 cnt_free
= end
- start
+ 1;
39 if (MT_EFUSE_USAGE_MAP_SIZE
- cnt_free
< 5) {
40 dev_err(dev
->mt76
.dev
,
41 "driver does not support default EEPROM\n");
48 static void mt76x0_set_chip_cap(struct mt76x02_dev
*dev
)
50 u16 nic_conf0
= mt76x02_eeprom_get(dev
, MT_EE_NIC_CONF_0
);
51 u16 nic_conf1
= mt76x02_eeprom_get(dev
, MT_EE_NIC_CONF_1
);
53 mt76x02_eeprom_parse_hw_cap(dev
);
54 dev_dbg(dev
->mt76
.dev
, "2GHz %d 5GHz %d\n",
55 dev
->mt76
.cap
.has_2ghz
, dev
->mt76
.cap
.has_5ghz
);
58 dev
->mt76
.cap
.has_2ghz
= false;
59 dev_dbg(dev
->mt76
.dev
, "mask out 2GHz support\n");
63 dev
->mt76
.cap
.has_5ghz
= false;
64 dev_dbg(dev
->mt76
.dev
, "mask out 5GHz support\n");
67 if (!mt76x02_field_valid(nic_conf1
& 0xff))
70 if (nic_conf1
& MT_EE_NIC_CONF_1_HW_RF_CTRL
)
71 dev_err(dev
->mt76
.dev
,
72 "driver does not support HW RF ctrl\n");
74 if (!mt76x02_field_valid(nic_conf0
>> 8))
77 if (FIELD_GET(MT_EE_NIC_CONF_0_RX_PATH
, nic_conf0
) > 1 ||
78 FIELD_GET(MT_EE_NIC_CONF_0_TX_PATH
, nic_conf0
) > 1)
79 dev_err(dev
->mt76
.dev
, "invalid tx-rx stream\n");
82 static void mt76x0_set_temp_offset(struct mt76x02_dev
*dev
)
86 val
= mt76x02_eeprom_get(dev
, MT_EE_2G_TARGET_POWER
) >> 8;
87 if (mt76x02_field_valid(val
))
88 dev
->cal
.rx
.temp_offset
= mt76x02_sign_extend(val
, 8);
90 dev
->cal
.rx
.temp_offset
= -10;
93 static void mt76x0_set_freq_offset(struct mt76x02_dev
*dev
)
95 struct mt76x02_rx_freq_cal
*caldata
= &dev
->cal
.rx
;
98 val
= mt76x02_eeprom_get(dev
, MT_EE_FREQ_OFFSET
);
99 if (!mt76x02_field_valid(val
))
101 caldata
->freq_offset
= val
;
103 val
= mt76x02_eeprom_get(dev
, MT_EE_TSSI_BOUND4
) >> 8;
104 if (!mt76x02_field_valid(val
))
107 caldata
->freq_offset
-= mt76x02_sign_extend(val
, 8);
110 void mt76x0_read_rx_gain(struct mt76x02_dev
*dev
)
112 struct ieee80211_channel
*chan
= dev
->mt76
.chandef
.chan
;
113 struct mt76x02_rx_freq_cal
*caldata
= &dev
->cal
.rx
;
114 s8 val
, lna_5g
[3], lna_2g
;
118 mt76x02_get_rx_gain(dev
, chan
->band
, &rssi_offset
, &lna_2g
, lna_5g
);
119 caldata
->lna_gain
= mt76x02_get_lna_gain(dev
, &lna_2g
, lna_5g
, chan
);
121 for (i
= 0; i
< ARRAY_SIZE(caldata
->rssi_offset
); i
++) {
122 val
= rssi_offset
>> (8 * i
);
123 if (val
< -10 || val
> 10)
126 caldata
->rssi_offset
[i
] = val
;
130 static s8
mt76x0_get_delta(struct mt76x02_dev
*dev
)
132 struct cfg80211_chan_def
*chandef
= &dev
->mt76
.chandef
;
135 if (chandef
->width
== NL80211_CHAN_WIDTH_80
) {
136 val
= mt76x02_eeprom_get(dev
, MT_EE_5G_TARGET_POWER
) >> 8;
137 } else if (chandef
->width
== NL80211_CHAN_WIDTH_40
) {
140 data
= mt76x02_eeprom_get(dev
, MT_EE_TX_POWER_DELTA_BW40
);
141 if (chandef
->chan
->band
== NL80211_BAND_5GHZ
)
149 return mt76x02_rate_power_val(val
);
152 void mt76x0_get_tx_power_per_rate(struct mt76x02_dev
*dev
,
153 struct ieee80211_channel
*chan
,
154 struct mt76_rate_power
*t
)
156 bool is_2ghz
= chan
->band
== NL80211_BAND_2GHZ
;
160 memset(t
, 0, sizeof(*t
));
162 /* cck 1M, 2M, 5.5M, 11M */
163 val
= mt76x02_eeprom_get(dev
, MT_EE_TX_POWER_BYRATE_BASE
);
164 t
->cck
[0] = t
->cck
[1] = s6_to_s8(val
);
165 t
->cck
[2] = t
->cck
[3] = s6_to_s8(val
>> 8);
167 /* ofdm 6M, 9M, 12M, 18M */
168 addr
= is_2ghz
? MT_EE_TX_POWER_BYRATE_BASE
+ 2 : 0x120;
169 val
= mt76x02_eeprom_get(dev
, addr
);
170 t
->ofdm
[0] = t
->ofdm
[1] = s6_to_s8(val
);
171 t
->ofdm
[2] = t
->ofdm
[3] = s6_to_s8(val
>> 8);
173 /* ofdm 24M, 36M, 48M, 54M */
174 addr
= is_2ghz
? MT_EE_TX_POWER_BYRATE_BASE
+ 4 : 0x122;
175 val
= mt76x02_eeprom_get(dev
, addr
);
176 t
->ofdm
[4] = t
->ofdm
[5] = s6_to_s8(val
);
177 t
->ofdm
[6] = t
->ofdm
[7] = s6_to_s8(val
>> 8);
179 /* ht-vht mcs 1ss 0, 1, 2, 3 */
180 addr
= is_2ghz
? MT_EE_TX_POWER_BYRATE_BASE
+ 6 : 0x124;
181 val
= mt76x02_eeprom_get(dev
, addr
);
182 t
->ht
[0] = t
->ht
[1] = t
->vht
[0] = t
->vht
[1] = s6_to_s8(val
);
183 t
->ht
[2] = t
->ht
[3] = t
->vht
[2] = t
->vht
[3] = s6_to_s8(val
>> 8);
185 /* ht-vht mcs 1ss 4, 5, 6 */
186 addr
= is_2ghz
? MT_EE_TX_POWER_BYRATE_BASE
+ 8 : 0x126;
187 val
= mt76x02_eeprom_get(dev
, addr
);
188 t
->ht
[4] = t
->ht
[5] = t
->vht
[4] = t
->vht
[5] = s6_to_s8(val
);
189 t
->ht
[6] = t
->ht
[7] = t
->vht
[6] = t
->vht
[7] = s6_to_s8(val
>> 8);
191 /* ht-vht mcs 1ss 0, 1, 2, 3 stbc */
192 addr
= is_2ghz
? MT_EE_TX_POWER_BYRATE_BASE
+ 14 : 0xec;
193 val
= mt76x02_eeprom_get(dev
, addr
);
194 t
->stbc
[0] = t
->stbc
[1] = s6_to_s8(val
);
195 t
->stbc
[2] = t
->stbc
[3] = s6_to_s8(val
>> 8);
197 /* ht-vht mcs 1ss 4, 5, 6 stbc */
198 addr
= is_2ghz
? MT_EE_TX_POWER_BYRATE_BASE
+ 16 : 0xee;
199 val
= mt76x02_eeprom_get(dev
, addr
);
200 t
->stbc
[4] = t
->stbc
[5] = s6_to_s8(val
);
201 t
->stbc
[6] = t
->stbc
[7] = s6_to_s8(val
>> 8);
203 /* vht mcs 8, 9 5GHz */
204 val
= mt76x02_eeprom_get(dev
, 0x132);
205 t
->vht
[8] = s6_to_s8(val
);
206 t
->vht
[9] = s6_to_s8(val
>> 8);
208 delta
= mt76x0_tssi_enabled(dev
) ? 0 : mt76x0_get_delta(dev
);
209 mt76x02_add_rate_power_offset(t
, delta
);
212 void mt76x0_get_power_info(struct mt76x02_dev
*dev
,
213 struct ieee80211_channel
*chan
, s8
*tp
)
215 static const struct mt76x0_chan_map
{
219 { 2, 0 }, { 4, 2 }, { 6, 4 }, { 8, 6 },
220 { 10, 8 }, { 12, 10 }, { 14, 12 }, { 38, 0 },
221 { 44, 2 }, { 48, 4 }, { 54, 6 }, { 60, 8 },
222 { 64, 10 }, { 102, 12 }, { 108, 14 }, { 112, 16 },
223 { 118, 18 }, { 124, 20 }, { 128, 22 }, { 134, 24 },
224 { 140, 26 }, { 151, 28 }, { 157, 30 }, { 161, 32 },
225 { 167, 34 }, { 171, 36 }, { 175, 38 },
231 if (mt76x0_tssi_enabled(dev
)) {
234 if (chan
->band
== NL80211_BAND_5GHZ
)
235 data
= mt76x02_eeprom_get(dev
, MT_EE_5G_TARGET_POWER
);
237 data
= mt76x02_eeprom_get(dev
, MT_EE_2G_TARGET_POWER
);
238 target_power
= (data
& 0xff) - dev
->mt76
.rate_power
.ofdm
[7];
239 *tp
= target_power
+ mt76x0_get_delta(dev
);
244 for (i
= 0; i
< ARRAY_SIZE(chan_map
); i
++) {
245 if (chan
->hw_value
<= chan_map
[i
].chan
) {
246 idx
= (chan
->hw_value
== chan_map
[i
].chan
);
247 offset
= chan_map
[i
].offset
;
251 if (i
== ARRAY_SIZE(chan_map
))
252 offset
= chan_map
[0].offset
;
254 if (chan
->band
== NL80211_BAND_2GHZ
) {
255 addr
= MT_EE_TX_POWER_DELTA_BW80
+ offset
;
257 switch (chan
->hw_value
) {
276 addr
= MT_EE_TX_POWER_0_GRP4_TSSI_SLOPE
+ 2 + offset
;
279 data
= mt76x02_eeprom_get(dev
, addr
);
280 *tp
= data
>> (8 * idx
);
281 if (*tp
< 0 || *tp
> 0x3f)
285 static int mt76x0_check_eeprom(struct mt76x02_dev
*dev
)
289 val
= get_unaligned_le16(dev
->mt76
.eeprom
.data
);
291 val
= get_unaligned_le16(dev
->mt76
.eeprom
.data
+
299 dev_err(dev
->mt76
.dev
, "EEPROM data check failed: %04x\n",
305 static int mt76x0_load_eeprom(struct mt76x02_dev
*dev
)
309 found
= mt76_eeprom_init(&dev
->mt76
, MT76X0_EEPROM_SIZE
);
313 if (found
&& !mt76x0_check_eeprom(dev
))
316 found
= mt76x0_efuse_physical_size_check(dev
);
320 return mt76x02_get_efuse_data(dev
, 0, dev
->mt76
.eeprom
.data
,
321 MT76X0_EEPROM_SIZE
, MT_EE_READ
);
324 int mt76x0_eeprom_init(struct mt76x02_dev
*dev
)
330 err
= mt76x0_load_eeprom(dev
);
334 data
= mt76x02_eeprom_get(dev
, MT_EE_VERSION
);
338 if (version
> MT76X0U_EE_MAX_VER
)
339 dev_warn(dev
->mt76
.dev
,
340 "Warning: unsupported EEPROM version %02hhx\n",
342 dev_info(dev
->mt76
.dev
, "EEPROM ver:%02hhx fae:%02hhx\n",
345 memcpy(dev
->mt76
.macaddr
, (u8
*)dev
->mt76
.eeprom
.data
+ MT_EE_MAC_ADDR
,
347 mt76_eeprom_override(&dev
->mt76
);
348 mt76x02_mac_setaddr(dev
, dev
->mt76
.macaddr
);
350 mt76x0_set_chip_cap(dev
);
351 mt76x0_set_freq_offset(dev
);
352 mt76x0_set_temp_offset(dev
);
357 MODULE_LICENSE("Dual BSD/GPL");