This source file includes following definitions.
- mt7615_efuse_read
- mt7615_efuse_init
- mt7615_eeprom_load
- mt7615_check_eeprom
- mt7615_eeprom_parse_hw_cap
- mt7615_eeprom_get_power_index
- mt7615_apply_cal_free_data
- mt7615_eeprom_init
1
2
3
4
5
6
7
8 #include "mt7615.h"
9 #include "eeprom.h"
10
11 static int mt7615_efuse_read(struct mt7615_dev *dev, u32 base,
12 u16 addr, u8 *data)
13 {
14 u32 val;
15 int i;
16
17 val = mt76_rr(dev, base + MT_EFUSE_CTRL);
18 val &= ~(MT_EFUSE_CTRL_AIN | MT_EFUSE_CTRL_MODE);
19 val |= FIELD_PREP(MT_EFUSE_CTRL_AIN, addr & ~0xf);
20 val |= MT_EFUSE_CTRL_KICK;
21 mt76_wr(dev, base + MT_EFUSE_CTRL, val);
22
23 if (!mt76_poll(dev, base + MT_EFUSE_CTRL, MT_EFUSE_CTRL_KICK, 0, 1000))
24 return -ETIMEDOUT;
25
26 udelay(2);
27
28 val = mt76_rr(dev, base + MT_EFUSE_CTRL);
29 if ((val & MT_EFUSE_CTRL_AOUT) == MT_EFUSE_CTRL_AOUT ||
30 WARN_ON_ONCE(!(val & MT_EFUSE_CTRL_VALID))) {
31 memset(data, 0x0, 16);
32 return 0;
33 }
34
35 for (i = 0; i < 4; i++) {
36 val = mt76_rr(dev, base + MT_EFUSE_RDATA(i));
37 put_unaligned_le32(val, data + 4 * i);
38 }
39
40 return 0;
41 }
42
43 static int mt7615_efuse_init(struct mt7615_dev *dev)
44 {
45 u32 val, base = mt7615_reg_map(dev, MT_EFUSE_BASE);
46 int i, len = MT7615_EEPROM_SIZE;
47 void *buf;
48
49 val = mt76_rr(dev, base + MT_EFUSE_BASE_CTRL);
50 if (val & MT_EFUSE_BASE_CTRL_EMPTY)
51 return 0;
52
53 dev->mt76.otp.data = devm_kzalloc(dev->mt76.dev, len, GFP_KERNEL);
54 dev->mt76.otp.size = len;
55 if (!dev->mt76.otp.data)
56 return -ENOMEM;
57
58 buf = dev->mt76.otp.data;
59 for (i = 0; i + 16 <= len; i += 16) {
60 int ret;
61
62 ret = mt7615_efuse_read(dev, base, i, buf + i);
63 if (ret)
64 return ret;
65 }
66
67 return 0;
68 }
69
70 static int mt7615_eeprom_load(struct mt7615_dev *dev)
71 {
72 int ret;
73
74 ret = mt76_eeprom_init(&dev->mt76, MT7615_EEPROM_SIZE);
75 if (ret < 0)
76 return ret;
77
78 return mt7615_efuse_init(dev);
79 }
80
81 static int mt7615_check_eeprom(struct mt76_dev *dev)
82 {
83 u16 val = get_unaligned_le16(dev->eeprom.data);
84
85 switch (val) {
86 case 0x7615:
87 return 0;
88 default:
89 return -EINVAL;
90 }
91 }
92
93 static void mt7615_eeprom_parse_hw_cap(struct mt7615_dev *dev)
94 {
95 u8 val, *eeprom = dev->mt76.eeprom.data;
96
97 val = FIELD_GET(MT_EE_NIC_WIFI_CONF_BAND_SEL,
98 eeprom[MT_EE_WIFI_CONF]);
99 switch (val) {
100 case MT_EE_5GHZ:
101 dev->mt76.cap.has_5ghz = true;
102 break;
103 case MT_EE_2GHZ:
104 dev->mt76.cap.has_2ghz = true;
105 break;
106 default:
107 dev->mt76.cap.has_2ghz = true;
108 dev->mt76.cap.has_5ghz = true;
109 break;
110 }
111 }
112
113 int mt7615_eeprom_get_power_index(struct mt7615_dev *dev,
114 struct ieee80211_channel *chan,
115 u8 chain_idx)
116 {
117 int index;
118
119 if (chain_idx > 3)
120 return -EINVAL;
121
122
123 if (mt7615_ext_pa_enabled(dev, chan->band)) {
124 if (chan->band == NL80211_BAND_2GHZ)
125 return MT_EE_EXT_PA_2G_TARGET_POWER;
126 else
127 return MT_EE_EXT_PA_5G_TARGET_POWER;
128 }
129
130
131 if (chan->band == NL80211_BAND_2GHZ) {
132 index = MT_EE_TX0_2G_TARGET_POWER + chain_idx * 6;
133 } else {
134 int group = mt7615_get_channel_group(chan->hw_value);
135
136 switch (chain_idx) {
137 case 1:
138 index = MT_EE_TX1_5G_G0_TARGET_POWER;
139 break;
140 case 2:
141 index = MT_EE_TX2_5G_G0_TARGET_POWER;
142 break;
143 case 3:
144 index = MT_EE_TX3_5G_G0_TARGET_POWER;
145 break;
146 case 0:
147 default:
148 index = MT_EE_TX0_5G_G0_TARGET_POWER;
149 break;
150 }
151 index += 5 * group;
152 }
153
154 return index;
155 }
156
157 static void mt7615_apply_cal_free_data(struct mt7615_dev *dev)
158 {
159 static const u16 ical[] = {
160 0x53, 0x54, 0x55, 0x56, 0x57, 0x5c, 0x5d, 0x62, 0x63, 0x68,
161 0x69, 0x6e, 0x6f, 0x73, 0x74, 0x78, 0x79, 0x82, 0x83, 0x87,
162 0x88, 0x8c, 0x8d, 0x91, 0x92, 0x96, 0x97, 0x9b, 0x9c, 0xa0,
163 0xa1, 0xaa, 0xab, 0xaf, 0xb0, 0xb4, 0xb5, 0xb9, 0xba, 0xf4,
164 0xf7, 0xff,
165 0x140, 0x141, 0x145, 0x146, 0x14a, 0x14b, 0x154, 0x155, 0x159,
166 0x15a, 0x15e, 0x15f, 0x163, 0x164, 0x168, 0x169, 0x16d, 0x16e,
167 0x172, 0x173, 0x17c, 0x17d, 0x181, 0x182, 0x186, 0x187, 0x18b,
168 0x18c
169 };
170 static const u16 ical_nocheck[] = {
171 0x110, 0x111, 0x112, 0x113, 0x114, 0x115, 0x116, 0x117, 0x118,
172 0x1b5, 0x1b6, 0x1b7, 0x3ac, 0x3ad, 0x3ae, 0x3af, 0x3b0, 0x3b1,
173 0x3b2
174 };
175 u8 *eeprom = dev->mt76.eeprom.data;
176 u8 *otp = dev->mt76.otp.data;
177 int i;
178
179 if (!otp)
180 return;
181
182 for (i = 0; i < ARRAY_SIZE(ical); i++)
183 if (!otp[ical[i]])
184 return;
185
186 for (i = 0; i < ARRAY_SIZE(ical); i++)
187 eeprom[ical[i]] = otp[ical[i]];
188
189 for (i = 0; i < ARRAY_SIZE(ical_nocheck); i++)
190 eeprom[ical_nocheck[i]] = otp[ical_nocheck[i]];
191 }
192
193 int mt7615_eeprom_init(struct mt7615_dev *dev)
194 {
195 int ret;
196
197 ret = mt7615_eeprom_load(dev);
198 if (ret < 0)
199 return ret;
200
201 ret = mt7615_check_eeprom(&dev->mt76);
202 if (ret && dev->mt76.otp.data)
203 memcpy(dev->mt76.eeprom.data, dev->mt76.otp.data,
204 MT7615_EEPROM_SIZE);
205 else
206 mt7615_apply_cal_free_data(dev);
207
208 mt7615_eeprom_parse_hw_cap(dev);
209 memcpy(dev->mt76.macaddr, dev->mt76.eeprom.data + MT_EE_MAC_ADDR,
210 ETH_ALEN);
211
212 mt76_eeprom_override(&dev->mt76);
213
214 return 0;
215 }