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