1 // SPDX-License-Identifier: ISC
2 /* Copyright (C) 2020 MediaTek Inc. */
3 
4 #include "mt7915.h"
5 #include "eeprom.h"
6 
7 static u32 mt7915_eeprom_read(struct mt7915_dev *dev, u32 offset)
8 {
9 	u8 *data = dev->mt76.eeprom.data;
10 
11 	if (data[offset] == 0xff && !dev->flash_mode)
12 		mt7915_mcu_get_eeprom(dev, offset);
13 
14 	return data[offset];
15 }
16 
17 static int mt7915_eeprom_load_precal(struct mt7915_dev *dev)
18 {
19 	struct mt76_dev *mdev = &dev->mt76;
20 	u32 val;
21 
22 	val = mt7915_eeprom_read(dev, MT_EE_DO_PRE_CAL);
23 	if (val != (MT_EE_WIFI_CAL_DPD | MT_EE_WIFI_CAL_GROUP))
24 		return 0;
25 
26 	val = MT_EE_CAL_GROUP_SIZE + MT_EE_CAL_DPD_SIZE;
27 	dev->cal = devm_kzalloc(mdev->dev, val, GFP_KERNEL);
28 	if (!dev->cal)
29 		return -ENOMEM;
30 
31 	return mt76_get_of_eeprom(mdev, dev->cal, MT_EE_PRECAL, val);
32 }
33 
34 static int mt7915_eeprom_load(struct mt7915_dev *dev)
35 {
36 	int ret;
37 
38 	ret = mt76_eeprom_init(&dev->mt76, MT7915_EEPROM_SIZE);
39 	if (ret < 0)
40 		return ret;
41 
42 	if (ret) {
43 		dev->flash_mode = true;
44 		ret = mt7915_eeprom_load_precal(dev);
45 	} else {
46 		memset(dev->mt76.eeprom.data, -1, MT7915_EEPROM_SIZE);
47 	}
48 
49 	return ret;
50 }
51 
52 static int mt7915_check_eeprom(struct mt7915_dev *dev)
53 {
54 	u8 *eeprom = dev->mt76.eeprom.data;
55 	u16 val;
56 
57 	mt7915_eeprom_read(dev, MT_EE_CHIP_ID);
58 	val = get_unaligned_le16(eeprom);
59 
60 	switch (val) {
61 	case 0x7915:
62 		return 0;
63 	default:
64 		return -EINVAL;
65 	}
66 }
67 
68 void mt7915_eeprom_parse_band_config(struct mt7915_phy *phy)
69 {
70 	struct mt7915_dev *dev = phy->dev;
71 	bool ext_phy = phy != &dev->phy;
72 	u32 val;
73 
74 	val = mt7915_eeprom_read(dev, MT_EE_WIFI_CONF + ext_phy);
75 	val = FIELD_GET(MT_EE_WIFI_CONF0_BAND_SEL, val);
76 	if (val == MT_EE_BAND_SEL_DEFAULT && dev->dbdc_support)
77 		val = ext_phy ? MT_EE_BAND_SEL_5GHZ : MT_EE_BAND_SEL_2GHZ;
78 
79 	switch (val) {
80 	case MT_EE_BAND_SEL_5GHZ:
81 		phy->mt76->cap.has_5ghz = true;
82 		break;
83 	case MT_EE_BAND_SEL_2GHZ:
84 		phy->mt76->cap.has_2ghz = true;
85 		break;
86 	default:
87 		phy->mt76->cap.has_2ghz = true;
88 		phy->mt76->cap.has_5ghz = true;
89 		break;
90 	}
91 }
92 
93 static void mt7915_eeprom_parse_hw_cap(struct mt7915_dev *dev)
94 {
95 	u8 nss, nss_band, *eeprom = dev->mt76.eeprom.data;
96 
97 	mt7915_eeprom_parse_band_config(&dev->phy);
98 
99 	/* read tx mask from eeprom */
100 	nss = FIELD_GET(MT_EE_WIFI_CONF0_TX_PATH, eeprom[MT_EE_WIFI_CONF]);
101 	if (!nss || nss > 4)
102 		nss = 4;
103 
104 	nss_band = nss;
105 
106 	if (dev->dbdc_support) {
107 		nss_band = FIELD_GET(MT_EE_WIFI_CONF3_TX_PATH_B0,
108 				     eeprom[MT_EE_WIFI_CONF + 3]);
109 		if (!nss_band || nss_band > 2)
110 			nss_band = 2;
111 
112 		if (nss_band >= nss)
113 			nss = 4;
114 	}
115 
116 	dev->chainmask = BIT(nss) - 1;
117 	dev->mphy.antenna_mask = BIT(nss_band) - 1;
118 	dev->mphy.chainmask = dev->mphy.antenna_mask;
119 }
120 
121 int mt7915_eeprom_init(struct mt7915_dev *dev)
122 {
123 	int ret;
124 
125 	ret = mt7915_eeprom_load(dev);
126 	if (ret < 0)
127 		return ret;
128 
129 	ret = mt7915_check_eeprom(dev);
130 	if (ret)
131 		return ret;
132 
133 	mt7915_eeprom_parse_hw_cap(dev);
134 	memcpy(dev->mphy.macaddr, dev->mt76.eeprom.data + MT_EE_MAC_ADDR,
135 	       ETH_ALEN);
136 
137 	mt76_eeprom_override(&dev->mphy);
138 
139 	return 0;
140 }
141 
142 int mt7915_eeprom_get_target_power(struct mt7915_dev *dev,
143 				   struct ieee80211_channel *chan,
144 				   u8 chain_idx)
145 {
146 	int index, target_power;
147 	bool tssi_on;
148 
149 	if (chain_idx > 3)
150 		return -EINVAL;
151 
152 	tssi_on = mt7915_tssi_enabled(dev, chan->band);
153 
154 	if (chan->band == NL80211_BAND_2GHZ) {
155 		index = MT_EE_TX0_POWER_2G + chain_idx * 3;
156 		target_power = mt7915_eeprom_read(dev, index);
157 
158 		if (!tssi_on)
159 			target_power += mt7915_eeprom_read(dev, index + 1);
160 	} else {
161 		int group = mt7915_get_channel_group(chan->hw_value);
162 
163 		index = MT_EE_TX0_POWER_5G + chain_idx * 12;
164 		target_power = mt7915_eeprom_read(dev, index + group);
165 
166 		if (!tssi_on)
167 			target_power += mt7915_eeprom_read(dev, index + 8);
168 	}
169 
170 	return target_power;
171 }
172 
173 s8 mt7915_eeprom_get_power_delta(struct mt7915_dev *dev, int band)
174 {
175 	u32 val;
176 	s8 delta;
177 
178 	if (band == NL80211_BAND_2GHZ)
179 		val = mt7915_eeprom_read(dev, MT_EE_RATE_DELTA_2G);
180 	else
181 		val = mt7915_eeprom_read(dev, MT_EE_RATE_DELTA_5G);
182 
183 	if (!(val & MT_EE_RATE_DELTA_EN))
184 		return 0;
185 
186 	delta = FIELD_GET(MT_EE_RATE_DELTA_MASK, val);
187 
188 	return val & MT_EE_RATE_DELTA_SIGN ? delta : -delta;
189 }
190 
191 const u8 mt7915_sku_group_len[] = {
192 	[SKU_CCK] = 4,
193 	[SKU_OFDM] = 8,
194 	[SKU_HT_BW20] = 8,
195 	[SKU_HT_BW40] = 9,
196 	[SKU_VHT_BW20] = 12,
197 	[SKU_VHT_BW40] = 12,
198 	[SKU_VHT_BW80] = 12,
199 	[SKU_VHT_BW160] = 12,
200 	[SKU_HE_RU26] = 12,
201 	[SKU_HE_RU52] = 12,
202 	[SKU_HE_RU106] = 12,
203 	[SKU_HE_RU242] = 12,
204 	[SKU_HE_RU484] = 12,
205 	[SKU_HE_RU996] = 12,
206 	[SKU_HE_RU2x996] = 12
207 };
208