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