0001
0002
0003
0004
0005
0006
0007 #include <asm/unaligned.h>
0008
0009 #include "mt76x02_eeprom.h"
0010
0011 static int
0012 mt76x02_efuse_read(struct mt76x02_dev *dev, u16 addr, u8 *data,
0013 enum mt76x02_eeprom_modes mode)
0014 {
0015 u32 val;
0016 int i;
0017
0018 val = mt76_rr(dev, MT_EFUSE_CTRL);
0019 val &= ~(MT_EFUSE_CTRL_AIN |
0020 MT_EFUSE_CTRL_MODE);
0021 val |= FIELD_PREP(MT_EFUSE_CTRL_AIN, addr & ~0xf);
0022 val |= FIELD_PREP(MT_EFUSE_CTRL_MODE, mode);
0023 val |= MT_EFUSE_CTRL_KICK;
0024 mt76_wr(dev, MT_EFUSE_CTRL, val);
0025
0026 if (!mt76_poll_msec(dev, MT_EFUSE_CTRL, MT_EFUSE_CTRL_KICK, 0, 1000))
0027 return -ETIMEDOUT;
0028
0029 udelay(2);
0030
0031 val = mt76_rr(dev, MT_EFUSE_CTRL);
0032 if ((val & MT_EFUSE_CTRL_AOUT) == MT_EFUSE_CTRL_AOUT) {
0033 memset(data, 0xff, 16);
0034 return 0;
0035 }
0036
0037 for (i = 0; i < 4; i++) {
0038 val = mt76_rr(dev, MT_EFUSE_DATA(i));
0039 put_unaligned_le32(val, data + 4 * i);
0040 }
0041
0042 return 0;
0043 }
0044
0045 int mt76x02_eeprom_copy(struct mt76x02_dev *dev,
0046 enum mt76x02_eeprom_field field,
0047 void *dest, int len)
0048 {
0049 if (field + len > dev->mt76.eeprom.size)
0050 return -1;
0051
0052 memcpy(dest, dev->mt76.eeprom.data + field, len);
0053 return 0;
0054 }
0055 EXPORT_SYMBOL_GPL(mt76x02_eeprom_copy);
0056
0057 int mt76x02_get_efuse_data(struct mt76x02_dev *dev, u16 base, void *buf,
0058 int len, enum mt76x02_eeprom_modes mode)
0059 {
0060 int ret, i;
0061
0062 for (i = 0; i + 16 <= len; i += 16) {
0063 ret = mt76x02_efuse_read(dev, base + i, buf + i, mode);
0064 if (ret)
0065 return ret;
0066 }
0067
0068 return 0;
0069 }
0070 EXPORT_SYMBOL_GPL(mt76x02_get_efuse_data);
0071
0072 void mt76x02_eeprom_parse_hw_cap(struct mt76x02_dev *dev)
0073 {
0074 u16 val = mt76x02_eeprom_get(dev, MT_EE_NIC_CONF_0);
0075
0076 switch (FIELD_GET(MT_EE_NIC_CONF_0_BOARD_TYPE, val)) {
0077 case BOARD_TYPE_5GHZ:
0078 dev->mphy.cap.has_5ghz = true;
0079 break;
0080 case BOARD_TYPE_2GHZ:
0081 dev->mphy.cap.has_2ghz = true;
0082 break;
0083 default:
0084 dev->mphy.cap.has_2ghz = true;
0085 dev->mphy.cap.has_5ghz = true;
0086 break;
0087 }
0088 }
0089 EXPORT_SYMBOL_GPL(mt76x02_eeprom_parse_hw_cap);
0090
0091 bool mt76x02_ext_pa_enabled(struct mt76x02_dev *dev, enum nl80211_band band)
0092 {
0093 u16 conf0 = mt76x02_eeprom_get(dev, MT_EE_NIC_CONF_0);
0094
0095 if (band == NL80211_BAND_5GHZ)
0096 return !(conf0 & MT_EE_NIC_CONF_0_PA_INT_5G);
0097 else
0098 return !(conf0 & MT_EE_NIC_CONF_0_PA_INT_2G);
0099 }
0100 EXPORT_SYMBOL_GPL(mt76x02_ext_pa_enabled);
0101
0102 void mt76x02_get_rx_gain(struct mt76x02_dev *dev, enum nl80211_band band,
0103 u16 *rssi_offset, s8 *lna_2g, s8 *lna_5g)
0104 {
0105 u16 val;
0106
0107 val = mt76x02_eeprom_get(dev, MT_EE_LNA_GAIN);
0108 *lna_2g = val & 0xff;
0109 lna_5g[0] = val >> 8;
0110
0111 val = mt76x02_eeprom_get(dev, MT_EE_RSSI_OFFSET_2G_1);
0112 lna_5g[1] = val >> 8;
0113
0114 val = mt76x02_eeprom_get(dev, MT_EE_RSSI_OFFSET_5G_1);
0115 lna_5g[2] = val >> 8;
0116
0117 if (!mt76x02_field_valid(lna_5g[1]))
0118 lna_5g[1] = lna_5g[0];
0119
0120 if (!mt76x02_field_valid(lna_5g[2]))
0121 lna_5g[2] = lna_5g[0];
0122
0123 if (band == NL80211_BAND_2GHZ)
0124 *rssi_offset = mt76x02_eeprom_get(dev, MT_EE_RSSI_OFFSET_2G_0);
0125 else
0126 *rssi_offset = mt76x02_eeprom_get(dev, MT_EE_RSSI_OFFSET_5G_0);
0127 }
0128 EXPORT_SYMBOL_GPL(mt76x02_get_rx_gain);
0129
0130 u8 mt76x02_get_lna_gain(struct mt76x02_dev *dev,
0131 s8 *lna_2g, s8 *lna_5g,
0132 struct ieee80211_channel *chan)
0133 {
0134 u16 val;
0135 u8 lna;
0136
0137 val = mt76x02_eeprom_get(dev, MT_EE_NIC_CONF_1);
0138 if (val & MT_EE_NIC_CONF_1_LNA_EXT_2G)
0139 *lna_2g = 0;
0140 if (val & MT_EE_NIC_CONF_1_LNA_EXT_5G)
0141 memset(lna_5g, 0, sizeof(s8) * 3);
0142
0143 if (chan->band == NL80211_BAND_2GHZ)
0144 lna = *lna_2g;
0145 else if (chan->hw_value <= 64)
0146 lna = lna_5g[0];
0147 else if (chan->hw_value <= 128)
0148 lna = lna_5g[1];
0149 else
0150 lna = lna_5g[2];
0151
0152 return lna != 0xff ? lna : 0;
0153 }
0154 EXPORT_SYMBOL_GPL(mt76x02_get_lna_gain);