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