2 * Copyright (C) 2014 Felix Fietkau <nbd@openwrt.org>
3 * Copyright (C) 2015 Jakub Kicinski <kubakici@wp.pl>
4 * Copyright (C) 2018 Stanislaw Gruszka <stf_xl@wp.pl>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2
8 * as published by the Free Software Foundation
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
17 #include <linux/mtd/mtd.h>
18 #include <linux/mtd/partitions.h>
19 #include <linux/etherdevice.h>
20 #include <asm/unaligned.h>
24 #define MT_MAP_READS DIV_ROUND_UP(MT_EFUSE_USAGE_MAP_SIZE, 16)
26 mt76x0_efuse_physical_size_check(struct mt76x0_dev *dev)
28 u8 data[MT_MAP_READS * 16];
30 u32 start = 0, end = 0, cnt_free;
32 ret = mt76x02_get_efuse_data(&dev->mt76, MT_EE_USAGE_MAP_START,
33 data, sizeof(data), MT_EE_PHYSICAL_READ);
37 for (i = 0; i < MT_EFUSE_USAGE_MAP_SIZE; i++)
40 start = MT_EE_USAGE_MAP_START + i;
41 end = MT_EE_USAGE_MAP_START + i;
43 cnt_free = end - start + 1;
45 if (MT_EFUSE_USAGE_MAP_SIZE - cnt_free < 5) {
46 dev_err(dev->mt76.dev,
47 "driver does not support default EEPROM\n");
55 mt76x0_set_chip_cap(struct mt76x0_dev *dev, u8 *eeprom)
57 enum mt76x2_board_type { BOARD_TYPE_2GHZ = 1, BOARD_TYPE_5GHZ = 2 };
58 u16 nic_conf0 = get_unaligned_le16(eeprom + MT_EE_NIC_CONF_0);
59 u16 nic_conf1 = get_unaligned_le16(eeprom + MT_EE_NIC_CONF_1);
61 dev_dbg(dev->mt76.dev, "NIC_CONF0: %04x NIC_CONF1: %04x\n", nic_conf0, nic_conf1);
63 switch (FIELD_GET(MT_EE_NIC_CONF_0_BOARD_TYPE, nic_conf0)) {
65 dev->mt76.cap.has_5ghz = true;
68 dev->mt76.cap.has_2ghz = true;
71 dev->mt76.cap.has_2ghz = true;
72 dev->mt76.cap.has_5ghz = true;
76 dev_dbg(dev->mt76.dev, "Has 2GHZ %d 5GHZ %d\n",
77 dev->mt76.cap.has_2ghz, dev->mt76.cap.has_5ghz);
79 if (!mt76x02_field_valid(nic_conf1 & 0xff))
82 if (nic_conf1 & MT_EE_NIC_CONF_1_HW_RF_CTRL)
83 dev_err(dev->mt76.dev,
84 "Error: this driver does not support HW RF ctrl\n");
86 if (!mt76x02_field_valid(nic_conf0 >> 8))
89 if (FIELD_GET(MT_EE_NIC_CONF_0_RX_PATH, nic_conf0) > 1 ||
90 FIELD_GET(MT_EE_NIC_CONF_0_TX_PATH, nic_conf0) > 1)
91 dev_err(dev->mt76.dev,
92 "Error: device has more than 1 RX/TX stream!\n");
96 mt76x0_set_temp_offset(struct mt76x0_dev *dev, u8 *eeprom)
98 u8 temp = eeprom[MT_EE_TEMP_OFFSET];
100 if (mt76x02_field_valid(temp))
101 dev->ee->temp_off = mt76x02_sign_extend(temp, 8);
103 dev->ee->temp_off = -10;
107 mt76x0_set_rf_freq_off(struct mt76x0_dev *dev, u8 *eeprom)
111 comp = eeprom[MT_EE_FREQ_OFFSET_COMPENSATION];
112 if (!mt76x02_field_valid(comp))
115 dev->ee->rf_freq_off = eeprom[MT_EE_FREQ_OFFSET];
116 if (!mt76x02_field_valid(dev->ee->rf_freq_off))
117 dev->ee->rf_freq_off = 0;
120 dev->ee->rf_freq_off -= comp & 0x7f;
122 dev->ee->rf_freq_off += comp;
125 void mt76x0_read_rx_gain(struct mt76x0_dev *dev)
127 struct ieee80211_channel *chan = dev->mt76.chandef.chan;
128 struct mt76x0_caldata *caldata = &dev->caldata;
129 s8 lna_5g[3], lna_2g;
132 mt76x02_get_rx_gain(&dev->mt76, chan->band, &rssi_offset,
134 caldata->lna_gain = mt76x02_get_lna_gain(&dev->mt76, &lna_2g,
140 mt76x0_set_rssi_offset(struct mt76x0_dev *dev, u8 *eeprom)
143 s8 *rssi_offset = dev->ee->rssi_offset_2ghz;
145 for (i = 0; i < 2; i++) {
146 rssi_offset[i] = eeprom[MT_EE_RSSI_OFFSET_2G_0 + i];
148 if (rssi_offset[i] < -10 || rssi_offset[i] > 10) {
149 dev_warn(dev->mt76.dev,
150 "Warning: EEPROM RSSI is invalid %02hhx\n",
156 rssi_offset = dev->ee->rssi_offset_5ghz;
158 for (i = 0; i < 3; i++) {
159 rssi_offset[i] = eeprom[MT_EE_RSSI_OFFSET_5G_0 + i];
161 if (rssi_offset[i] < -10 || rssi_offset[i] > 10) {
162 dev_warn(dev->mt76.dev,
163 "Warning: EEPROM RSSI is invalid %02hhx\n",
171 calc_bw40_power_rate(u32 value, int delta)
176 for (i = 0; i < 4; i++) {
177 tmp = s6_to_int((value >> i*8) & 0xff) + delta;
178 ret |= (u32)(int_to_s6(tmp)) << i*8;
189 if (!mt76x02_field_valid(val) || !(val & BIT(7)))
202 mt76x0_set_tx_power_per_rate(struct mt76x0_dev *dev, u8 *eeprom)
204 s8 bw40_delta_2g, bw40_delta_5g;
208 bw40_delta_2g = get_delta(eeprom[MT_EE_TX_POWER_DELTA_BW40]);
209 bw40_delta_5g = get_delta(eeprom[MT_EE_TX_POWER_DELTA_BW40 + 1]);
211 for (i = 0; i < 5; i++) {
212 val = get_unaligned_le32(eeprom + MT_EE_TX_POWER_BYRATE(i));
214 /* Skip last 16 bits. */
218 dev->ee->tx_pwr_cfg_2g[i][0] = val;
219 dev->ee->tx_pwr_cfg_2g[i][1] = calc_bw40_power_rate(val, bw40_delta_2g);
222 /* Reading per rate tx power for 5 GHz band is a bit more complex. Note
223 * we mix 16 bit and 32 bit reads and sometimes do shifts.
225 val = get_unaligned_le16(eeprom + 0x120);
227 dev->ee->tx_pwr_cfg_5g[0][0] = val;
228 dev->ee->tx_pwr_cfg_5g[0][1] = calc_bw40_power_rate(val, bw40_delta_5g);
230 val = get_unaligned_le32(eeprom + 0x122);
231 dev->ee->tx_pwr_cfg_5g[1][0] = val;
232 dev->ee->tx_pwr_cfg_5g[1][1] = calc_bw40_power_rate(val, bw40_delta_5g);
234 val = get_unaligned_le16(eeprom + 0x126);
235 dev->ee->tx_pwr_cfg_5g[2][0] = val;
236 dev->ee->tx_pwr_cfg_5g[2][1] = calc_bw40_power_rate(val, bw40_delta_5g);
238 val = get_unaligned_le16(eeprom + 0xec);
240 dev->ee->tx_pwr_cfg_5g[3][0] = val;
241 dev->ee->tx_pwr_cfg_5g[3][1] = calc_bw40_power_rate(val, bw40_delta_5g);
243 val = get_unaligned_le16(eeprom + 0xee);
244 dev->ee->tx_pwr_cfg_5g[4][0] = val;
245 dev->ee->tx_pwr_cfg_5g[4][1] = calc_bw40_power_rate(val, bw40_delta_5g);
249 mt76x0_set_tx_power_per_chan(struct mt76x0_dev *dev, u8 *eeprom)
254 for (i = 0; i < 14; i++) {
255 tx_pwr = eeprom[MT_EE_TX_POWER_DELTA_BW80 + i];
256 if (tx_pwr <= 0x3f && tx_pwr > 0)
257 dev->ee->tx_pwr_per_chan[i] = tx_pwr;
259 dev->ee->tx_pwr_per_chan[i] = 5;
262 for (i = 0; i < 40; i++) {
263 tx_pwr = eeprom[MT_EE_TX_POWER_0_GRP4_TSSI_SLOPE + 2 + i];
264 if (tx_pwr <= 0x3f && tx_pwr > 0)
265 dev->ee->tx_pwr_per_chan[14 + i] = tx_pwr;
267 dev->ee->tx_pwr_per_chan[14 + i] = 5;
270 dev->ee->tx_pwr_per_chan[54] = dev->ee->tx_pwr_per_chan[22];
271 dev->ee->tx_pwr_per_chan[55] = dev->ee->tx_pwr_per_chan[28];
272 dev->ee->tx_pwr_per_chan[56] = dev->ee->tx_pwr_per_chan[34];
273 dev->ee->tx_pwr_per_chan[57] = dev->ee->tx_pwr_per_chan[44];
277 mt76x0_eeprom_init(struct mt76x0_dev *dev)
282 ret = mt76x0_efuse_physical_size_check(dev);
286 ret = mt76_eeprom_init(&dev->mt76, MT76X0_EEPROM_SIZE);
290 dev->ee = devm_kzalloc(dev->mt76.dev, sizeof(*dev->ee), GFP_KERNEL);
294 eeprom = kmalloc(MT76X0_EEPROM_SIZE, GFP_KERNEL);
298 ret = mt76x02_get_efuse_data(&dev->mt76, 0, eeprom,
299 MT76X0_EEPROM_SIZE, MT_EE_READ);
303 if (eeprom[MT_EE_VERSION + 1] > MT76X0U_EE_MAX_VER)
304 dev_warn(dev->mt76.dev,
305 "Warning: unsupported EEPROM version %02hhx\n",
306 eeprom[MT_EE_VERSION + 1]);
307 dev_info(dev->mt76.dev, "EEPROM ver:%02hhx fae:%02hhx\n",
308 eeprom[MT_EE_VERSION + 1], eeprom[MT_EE_VERSION]);
310 mt76x02_mac_setaddr(&dev->mt76, eeprom + MT_EE_MAC_ADDR);
311 mt76x0_set_chip_cap(dev, eeprom);
312 mt76x0_set_rf_freq_off(dev, eeprom);
313 mt76x0_set_temp_offset(dev, eeprom);
314 mt76x0_set_rssi_offset(dev, eeprom);
315 dev->chainmask = 0x0101;
317 mt76x0_set_tx_power_per_rate(dev, eeprom);
318 mt76x0_set_tx_power_per_chan(dev, eeprom);
325 MODULE_LICENSE("Dual BSD/GPL");