From ce38099baef9ad400b8c442a42345e354165596d Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 16 Dec 2015 03:13:05 +0100 Subject: [PATCH] mt7603: send eeprom data to MCU Signed-off-by: Felix Fietkau --- mt7603.h | 1 + mt7603_eeprom.h | 94 +++++++++++++++++++++++++++++++++++++++++ mt7603_init.c | 1 + mt7603_mcu.c | 108 +++++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 202 insertions(+), 2 deletions(-) create mode 100644 mt7603_eeprom.h diff --git a/mt7603.h b/mt7603.h index 45e12a26..805adfb4 100644 --- a/mt7603.h +++ b/mt7603.h @@ -118,6 +118,7 @@ void mt7603_mac_stop(struct mt7603_dev *dev); int mt7603_set_channel(struct mt7603_dev *dev, struct cfg80211_chan_def *def); int mt7603_mcu_set_channel(struct mt7603_dev *dev); int mt7603_mcu_reg_read(struct mt7603_dev *dev, u32 reg, u32 *val, bool rf); +int mt7603_mcu_set_eeprom(struct mt7603_dev *dev); void mt7603_wtbl_init(struct mt7603_dev *dev, int idx, const u8 *addr); void mt7603_wtbl_clear(struct mt7603_dev *dev, int idx); diff --git a/mt7603_eeprom.h b/mt7603_eeprom.h new file mode 100644 index 00000000..3c33e2a8 --- /dev/null +++ b/mt7603_eeprom.h @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2015 Felix Fietkau + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __MT7603_EEPROM_H +#define __MT7603_EEPROM_H + +#include "mt7603.h" + +enum mt7603_eeprom_field { + MT_EE_CHIP_ID = 0x000, + MT_EE_VERSION = 0x002, + MT_EE_MAC_ADDR = 0x004, + MT_EE_NIC_CONF_0 = 0x034, + MT_EE_NIC_CONF_1 = 0x036, + MT_EE_NIC_CONF_2 = 0x042, + + MT_EE_XTAL_TRIM_1 = 0x03a, + + MT_EE_WIFI_RF_SETTING = 0x048, + + MT_EE_TX_POWER_DELTA_BW40 = 0x050, + MT_EE_TX_POWER_DELTA_BW80 = 0x052, + + MT_EE_TX_POWER_EXT_PA_5G = 0x054, + + MT_EE_TEMP_SENSOR_CAL = 0x055, + + MT_EE_TX_POWER_0_START_2G = 0x056, + MT_EE_TX_POWER_1_START_2G = 0x05c, + + /* used as byte arrays */ +#define MT_TX_POWER_GROUP_SIZE_5G 5 +#define MT_TX_POWER_GROUPS_5G 6 + MT_EE_TX_POWER_0_START_5G = 0x062, + + MT_EE_TX_POWER_0_GRP3_TX_POWER_DELTA = 0x074, + MT_EE_TX_POWER_0_GRP4_TSSI_SLOPE = 0x076, + + MT_EE_TX_POWER_1_START_5G = 0x080, + + + MT_EE_TX_POWER_CCK = 0x0a0, + MT_EE_TX_POWER_OFDM_2G_6M = 0x0a2, + MT_EE_TX_POWER_OFDM_2G_24M = 0x0a4, + MT_EE_TX_POWER_OFDM_2G_54M = 0x0a6, + MT_EE_TX_POWER_HT_BPSK_QPSK = 0x0a8, + MT_EE_TX_POWER_HT_16_64_QAM = 0x0aa, + MT_EE_TX_POWER_HT_64_QAM = 0x0ac, + + MT_EE_ELAN_RX_MODE_GAIN = 0x0c0, + MT_EE_ELAN_RX_MODE_NF = 0x0c1, + MT_EE_ELAN_RX_MODE_P1DB = 0x0c2, + + MT_EE_ELAN_BYPASS_MODE_GAIN = 0x0c3, + MT_EE_ELAN_BYPASS_MODE_NF = 0x0c4, + MT_EE_ELAN_BYPASS_MODE_P1DB = 0x0c5, + + MT_EE_STEP_NUM_NEG_6_7 = 0x0c6, + MT_EE_STEP_NUM_NEG_4_5 = 0x0c8, + MT_EE_STEP_NUM_NEG_2_3 = 0x0ca, + MT_EE_STEP_NUM_NEG_0_1 = 0x0cc, + + MT_EE_REF_STEP_24G = 0x0ce, + + MT_EE_STEP_NUM_PLUS_1_2 = 0x0d0, + MT_EE_STEP_NUM_PLUS_3_4 = 0x0d2, + MT_EE_STEP_NUM_PLUS_5_6 = 0x0d4, + MT_EE_STEP_NUM_PLUS_7 = 0x0d6, + + MT_EE_XTAL_FREQ_OFFSET = 0x0f4, + MT_EE_XTAL_TRIM_2_COMP = 0x0f5, + MT_EE_XTAL_TRIM_3_COMP = 0x0f6, + MT_EE_XTAL_WF_RFCAL = 0x0f7, + + __MT_EE_MAX +}; + +enum mt7603_eeprom_source { + MT_EE_SRC_PROM, + MT_EE_SRC_EFUSE, + MT_EE_SRC_FLASH, +}; + +#endif diff --git a/mt7603_init.c b/mt7603_init.c index 5375f781..9e00a610 100644 --- a/mt7603_init.c +++ b/mt7603_init.c @@ -240,6 +240,7 @@ mt7603_init_hardware(struct mt7603_dev *dev) return ret; mt7603_dma_sched_init(dev); + mt7603_mcu_set_eeprom(dev); mt7603_phy_init(dev); mt7603_mac_init(dev); diff --git a/mt7603_mcu.c b/mt7603_mcu.c index e1182be3..ee503332 100644 --- a/mt7603_mcu.c +++ b/mt7603_mcu.c @@ -14,6 +14,9 @@ #include #include "mt7603.h" #include "mt7603_mcu.h" +#include "mt7603_eeprom.h" + +#define MCU_SKB_RESERVE 8 struct mt7603_fw_trailer { char fw_ver[10]; @@ -26,9 +29,10 @@ mt7603_mcu_msg_alloc(struct mt7603_dev *dev, const void *data, int len) { struct sk_buff *skb; - skb = alloc_skb(len + sizeof(struct mt7603_mcu_txd), GFP_KERNEL); + skb = alloc_skb(len + sizeof(struct mt7603_mcu_txd), + GFP_KERNEL); skb_reserve(skb, sizeof(struct mt7603_mcu_txd)); - if (len) + if (data && len) memcpy(skb_put(skb, len), data, len); return skb; @@ -285,6 +289,106 @@ int mt7603_mcu_init(struct mt7603_dev *dev) return mt7603_load_firmware(dev); } +int mt7603_mcu_set_eeprom(struct mt7603_dev *dev) +{ + static const u16 req_fields[] = { +#define WORD(_start) \ + _start, \ + _start + 1 +#define GROUP_2G(_start) \ + WORD(_start), \ + WORD(_start + 2), \ + WORD(_start + 4) + + MT_EE_NIC_CONF_0 + 1, + WORD(MT_EE_NIC_CONF_1), + MT_EE_WIFI_RF_SETTING, + MT_EE_TX_POWER_DELTA_BW40, + MT_EE_TX_POWER_DELTA_BW80 + 1, + MT_EE_TX_POWER_EXT_PA_5G, + MT_EE_TEMP_SENSOR_CAL, + GROUP_2G(MT_EE_TX_POWER_0_START_2G), + GROUP_2G(MT_EE_TX_POWER_1_START_2G), + WORD(MT_EE_TX_POWER_CCK), + WORD(MT_EE_TX_POWER_OFDM_2G_6M), + WORD(MT_EE_TX_POWER_OFDM_2G_24M), + WORD(MT_EE_TX_POWER_OFDM_2G_54M), + WORD(MT_EE_TX_POWER_HT_BPSK_QPSK), + WORD(MT_EE_TX_POWER_HT_16_64_QAM), + WORD(MT_EE_TX_POWER_HT_64_QAM), + MT_EE_ELAN_RX_MODE_GAIN, + MT_EE_ELAN_RX_MODE_NF, + MT_EE_ELAN_RX_MODE_P1DB, + MT_EE_ELAN_BYPASS_MODE_GAIN, + MT_EE_ELAN_BYPASS_MODE_NF, + MT_EE_ELAN_BYPASS_MODE_P1DB, + WORD(MT_EE_STEP_NUM_NEG_6_7), + WORD(MT_EE_STEP_NUM_NEG_4_5), + WORD(MT_EE_STEP_NUM_NEG_2_3), + WORD(MT_EE_STEP_NUM_NEG_0_1), + WORD(MT_EE_REF_STEP_24G), + WORD(MT_EE_STEP_NUM_PLUS_1_2), + WORD(MT_EE_STEP_NUM_PLUS_3_4), + WORD(MT_EE_STEP_NUM_PLUS_5_6), + MT_EE_STEP_NUM_PLUS_7, + MT_EE_XTAL_FREQ_OFFSET, + MT_EE_XTAL_TRIM_2_COMP, + MT_EE_XTAL_TRIM_3_COMP, + MT_EE_XTAL_WF_RFCAL, + + /* unknown fields below */ + WORD(0x24), + 0x34, + 0x39, + 0x3b, + WORD(0x42), + WORD(0x9e), + 0xf2, + WORD(0xf8), + 0xfa, + 0x12e, + WORD(0x130), WORD(0x132), WORD(0x134), WORD(0x136), + WORD(0x138), WORD(0x13a), WORD(0x13c), WORD(0x13e), + +#undef GROUP_2G +#undef WORD + + }; + struct req_data { + u16 addr; + u8 val; + u8 pad; + } __packed; + struct { + u8 buffer_mode; + u8 len; + u8 pad[2]; + } req_hdr = { + .buffer_mode = 1, + .len = ARRAY_SIZE(req_fields) - 1, + }; + struct sk_buff *skb; + struct req_data *data; + const int size = 0xff * sizeof(struct req_data); + u8 *eep = (u8 *) dev->mt76.eeprom.data; + int i; + + BUILD_BUG_ON(ARRAY_SIZE(req_fields) * sizeof(*data) > size); + + skb = mt7603_mcu_msg_alloc(dev, NULL, size + sizeof(req_hdr)); + memcpy(skb_put(skb, sizeof(req_hdr)), &req_hdr, sizeof(req_hdr)); + data = (struct req_data *) skb_put(skb, size); + memset(data, 0, size); + + for (i = 0; i < ARRAY_SIZE(req_fields); i++) { + data[i].addr = cpu_to_le16(req_fields[i]); + data[i].val = eep[req_fields[i]]; + data[i].pad = 0; + } + + return mt7603_mcu_msg_send(dev, skb, MCU_EXT_CMD_EFUSE_BUFFER_MODE, MCU_Q_SET, NULL); +} + static int mt7603_mcu_set_tx_power(struct mt7603_dev *dev) { struct {