wifi: mt76: mt7996: apply calibration-free data from OTP

Before sending the current EEPROM data to the firmware, read the
calibration-free data (FT data) from the efuse and merge it with
the existing EEPROM data.

Co-developed-by: Shayne Chen <[email protected]>
Signed-off-by: Shayne Chen <[email protected]>
Signed-off-by: StanleyYP Wang <[email protected]>
Link: https://patch.msgid.link/[email protected]
Signed-off-by: Felix Fietkau <[email protected]>
This commit is contained in:
StanleyYP Wang
2026-02-21 08:56:45 +00:00
committed by Felix Fietkau
parent f656567eff
commit 36c59c31bf
2 changed files with 157 additions and 19 deletions
+152 -19
View File
@@ -3950,7 +3950,152 @@ int mt7996_mcu_set_chan_info(struct mt7996_phy *phy, u16 tag)
&req, sizeof(req), true);
}
static int mt7996_mcu_set_eeprom_flash(struct mt7996_dev *dev)
static int
mt7996_mcu_get_cal_free_data(struct mt7996_dev *dev)
{
#define MT_EE_7977BN_OFFSET (0x1200 - 0x500)
struct cal_free_data {
u16 adie_offs;
u16 eep_offs;
};
static const struct cal_free_data cal_7975[] = {
{ 0x5cd, 0x451 }, { 0x5cf, 0x453 }, { 0x5d1, 0x455 },
{ 0x5d3, 0x457 }, { 0x6c0, 0x44c }, { 0x6c1, 0x44d },
{ 0x6c2, 0x44e }, { 0x6c3, 0x44f }, { 0x7a1, 0xba1 },
{ 0x7a6, 0xba6 }, { 0x7a8, 0xba8 }, { 0x7aa, 0xbaa },
};
static const struct cal_free_data cal_7976[] = {
{ 0x4c, 0x44c }, { 0x4d, 0x44d }, { 0x4e, 0x44e },
{ 0x4f, 0x44f }, { 0x50, 0x450 }, { 0x51, 0x451 },
{ 0x53, 0x453 }, { 0x55, 0x455 }, { 0x57, 0x457 },
{ 0x59, 0x459 }, { 0x70, 0x470 }, { 0x71, 0x471 },
{ 0x790, 0xb90 }, { 0x791, 0xb91 }, { 0x794, 0xb94 },
{ 0x795, 0xb95 }, { 0x7a6, 0xba6 }, { 0x7a8, 0xba8 },
{ 0x7aa, 0xbaa },
};
static const struct cal_free_data cal_7977[] = {
{ 0x4c, 0x124c }, { 0x4d, 0x124d }, { 0x4e, 0x124e },
{ 0x4f, 0x124f }, { 0x50, 0x1250 }, { 0x51, 0x1251 },
{ 0x53, 0x1253 }, { 0x55, 0x1255 }, { 0x57, 0x1257 },
{ 0x59, 0x1259 }, { 0x69, 0x1269 }, { 0x6a, 0x126a },
{ 0x7a, 0x127a }, { 0x7b, 0x127b }, { 0x7c, 0x127c },
{ 0x7d, 0x127d }, { 0x7e, 0x127e },
};
static const struct cal_free_data cal_7978[] = {
{ 0x91, 0xb91 }, { 0x95, 0xb95 }, { 0x100, 0x480 },
{ 0x102, 0x482 }, { 0x104, 0x484 }, { 0x106, 0x486 },
{ 0x107, 0x487 }, { 0x108, 0x488 }, { 0x109, 0x489 },
{ 0x10a, 0x48a }, { 0x10b, 0x48b }, { 0x10c, 0x48c },
{ 0x10e, 0x48e }, { 0x110, 0x490 },
};
static const struct cal_free_data cal_7979[] = {
{ 0x4c, 0x124c }, { 0x4d, 0x124d }, { 0x4e, 0x124e },
{ 0x4f, 0x124f }, { 0x50, 0x1250 }, { 0x51, 0x1251 },
{ 0x53, 0x1253 }, { 0x55, 0x1255 }, { 0x57, 0x1257 },
{ 0x59, 0x1259 }, { 0x69, 0x1269 }, { 0x6a, 0x126a },
{ 0x7a, 0x127a }, { 0x7b, 0x127b }, { 0x7c, 0x127c },
{ 0x7e, 0x127e }, { 0x80, 0x1280 },
};
const struct cal_free_data *cal_arr[__MT_MAX_BAND];
u16 cal_arr_len[__MT_MAX_BAND] = {};
u8 *eeprom = (u8 *)dev->mt76.eeprom.data;
int band, i, ret;
#define CAL_ARR(_band, _adie) do { \
cal_arr[_band] = cal_##_adie; \
cal_arr_len[_band] = ARRAY_SIZE(cal_##_adie); \
} while (0)
switch (mt76_chip(&dev->mt76)) {
case MT7996_DEVICE_ID:
/* adie 0 */
if (dev->var.fem == MT7996_FEM_INT &&
dev->var.type != MT7996_VAR_TYPE_233)
CAL_ARR(0, 7975);
else
CAL_ARR(0, 7976);
/* adie 1 */
if (dev->var.type == MT7996_VAR_TYPE_444)
CAL_ARR(1, 7977);
/* adie 2 */
CAL_ARR(2, 7977);
break;
case MT7992_DEVICE_ID:
/* adie 0 */
if (dev->var.type == MT7992_VAR_TYPE_44 &&
dev->var.fem != MT7996_FEM_EXT)
CAL_ARR(0, 7975);
else if (dev->var.type == MT7992_VAR_TYPE_24)
CAL_ARR(0, 7978);
else
CAL_ARR(0, 7976);
/* adie 1 */
if (dev->var.type == MT7992_VAR_TYPE_44 &&
dev->var.fem != MT7996_FEM_INT)
CAL_ARR(1, 7977);
else if (dev->var.type != MT7992_VAR_TYPE_23)
CAL_ARR(1, 7979);
break;
case MT7990_DEVICE_ID:
/* adie 0 */
CAL_ARR(0, 7976);
break;
default:
return -EINVAL;
}
for (band = 0; band < __MT_MAX_BAND; band++) {
const struct cal_free_data *cal;
u16 prev_block_idx = -1;
u16 adie_base;
if (!cal_arr_len[band])
continue;
if (band == MT_BAND0)
adie_base = MT7996_EFUSE_BASE_OFFS_ADIE0;
else if (band == MT_BAND1 && is_mt7992(&dev->mt76))
adie_base = MT7992_EFUSE_BASE_OFFS_ADIE1;
else if (band == MT_BAND1)
adie_base = MT7996_EFUSE_BASE_OFFS_ADIE1;
else
adie_base = MT7996_EFUSE_BASE_OFFS_ADIE2;
cal = cal_arr[band];
for (i = 0; i < cal_arr_len[band]; i++) {
u16 adie_offset = cal[i].adie_offs + adie_base;
u16 eep_offset = cal[i].eep_offs;
u16 block_idx = adie_offset / MT7996_EEPROM_BLOCK_SIZE;
u16 offset = adie_offset % MT7996_EEPROM_BLOCK_SIZE;
u8 buf[MT7996_EEPROM_BLOCK_SIZE];
if (is_mt7996(&dev->mt76) && band == MT_BAND1 &&
dev->var.type == MT7996_VAR_TYPE_444)
eep_offset -= MT_EE_7977BN_OFFSET;
if (prev_block_idx != block_idx) {
ret = mt7996_mcu_get_eeprom(dev, adie_offset, buf,
MT7996_EEPROM_BLOCK_SIZE,
EEPROM_MODE_EFUSE);
if (ret) {
if (ret != -EINVAL)
return ret;
prev_block_idx = -1;
continue;
}
}
eeprom[eep_offset] = buf[offset];
prev_block_idx = block_idx;
}
}
return 0;
}
int mt7996_mcu_set_eeprom(struct mt7996_dev *dev)
{
#define MAX_PAGE_IDX_MASK GENMASK(7, 5)
#define PAGE_IDX_MASK GENMASK(4, 2)
@@ -3962,11 +4107,15 @@ static int mt7996_mcu_set_eeprom_flash(struct mt7996_dev *dev)
u16 eeprom_size = MT7996_EEPROM_SIZE;
u8 total = DIV_ROUND_UP(eeprom_size, PER_PAGE_SIZE);
u8 *eep = (u8 *)dev->mt76.eeprom.data;
int eep_len, i;
int ret, eep_len, i;
ret = mt7996_mcu_get_cal_free_data(dev);
if (ret)
return ret;
for (i = 0; i < total; i++, eep += eep_len) {
struct sk_buff *skb;
int ret, msg_len;
int msg_len;
if (i == total - 1 && !!(eeprom_size % PER_PAGE_SIZE))
eep_len = eeprom_size % PER_PAGE_SIZE;
@@ -3995,22 +4144,6 @@ static int mt7996_mcu_set_eeprom_flash(struct mt7996_dev *dev)
return 0;
}
int mt7996_mcu_set_eeprom(struct mt7996_dev *dev)
{
struct mt7996_mcu_eeprom_update req = {
.tag = cpu_to_le16(UNI_EFUSE_BUFFER_MODE),
.len = cpu_to_le16(sizeof(req) - 4),
.buffer_mode = EE_MODE_EFUSE,
.format = EE_FORMAT_WHOLE
};
if (dev->eeprom_mode != EEPROM_MODE_EFUSE)
return mt7996_mcu_set_eeprom_flash(dev);
return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(EFUSE_CTRL),
&req, sizeof(req), true);
}
int mt7996_mcu_get_eeprom(struct mt7996_dev *dev, u32 offset, u8 *buf, u32 buf_len,
enum mt7996_eeprom_mode mode)
{
+5
View File
@@ -184,6 +184,11 @@ enum mt7996_eeprom_mode {
EEPROM_MODE_EXT,
};
#define MT7996_EFUSE_BASE_OFFS_ADIE0 0x400
#define MT7996_EFUSE_BASE_OFFS_ADIE1 0x1e00
#define MT7996_EFUSE_BASE_OFFS_ADIE2 0x1200
#define MT7992_EFUSE_BASE_OFFS_ADIE1 0x1200
enum mt7996_txq_id {
MT7996_TXQ_FWDL = 16,
MT7996_TXQ_MCU_WM,