Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: ISC
0002 /* Copyright (C) 2019 MediaTek Inc.
0003  *
0004  * Author: Ryder Lee <ryder.lee@mediatek.com>
0005  *         Felix Fietkau <nbd@nbd.name>
0006  */
0007 
0008 #include <linux/of.h>
0009 #include "mt7615.h"
0010 #include "eeprom.h"
0011 
0012 static int mt7615_efuse_read(struct mt7615_dev *dev, u32 base,
0013                  u16 addr, u8 *data)
0014 {
0015     u32 val;
0016     int i;
0017 
0018     val = mt76_rr(dev, base + MT_EFUSE_CTRL);
0019     val &= ~(MT_EFUSE_CTRL_AIN | MT_EFUSE_CTRL_MODE);
0020     val |= FIELD_PREP(MT_EFUSE_CTRL_AIN, addr & ~0xf);
0021     val |= MT_EFUSE_CTRL_KICK;
0022     mt76_wr(dev, base + MT_EFUSE_CTRL, val);
0023 
0024     if (!mt76_poll(dev, base + MT_EFUSE_CTRL, MT_EFUSE_CTRL_KICK, 0, 1000))
0025         return -ETIMEDOUT;
0026 
0027     udelay(2);
0028 
0029     val = mt76_rr(dev, base + MT_EFUSE_CTRL);
0030     if ((val & MT_EFUSE_CTRL_AOUT) == MT_EFUSE_CTRL_AOUT ||
0031         WARN_ON_ONCE(!(val & MT_EFUSE_CTRL_VALID))) {
0032         memset(data, 0x0, 16);
0033         return 0;
0034     }
0035 
0036     for (i = 0; i < 4; i++) {
0037         val = mt76_rr(dev, base + MT_EFUSE_RDATA(i));
0038         put_unaligned_le32(val, data + 4 * i);
0039     }
0040 
0041     return 0;
0042 }
0043 
0044 static int mt7615_efuse_init(struct mt7615_dev *dev, u32 base)
0045 {
0046     int i, len = MT7615_EEPROM_SIZE;
0047     void *buf;
0048     u32 val;
0049 
0050     val = mt76_rr(dev, base + MT_EFUSE_BASE_CTRL);
0051     if (val & MT_EFUSE_BASE_CTRL_EMPTY)
0052         return 0;
0053 
0054     dev->mt76.otp.data = devm_kzalloc(dev->mt76.dev, len, GFP_KERNEL);
0055     dev->mt76.otp.size = len;
0056     if (!dev->mt76.otp.data)
0057         return -ENOMEM;
0058 
0059     buf = dev->mt76.otp.data;
0060     for (i = 0; i + 16 <= len; i += 16) {
0061         int ret;
0062 
0063         ret = mt7615_efuse_read(dev, base, i, buf + i);
0064         if (ret)
0065             return ret;
0066     }
0067 
0068     return 0;
0069 }
0070 
0071 static int mt7615_eeprom_load(struct mt7615_dev *dev, u32 addr)
0072 {
0073     int ret;
0074 
0075     ret = mt76_eeprom_init(&dev->mt76, MT7615_EEPROM_FULL_SIZE);
0076     if (ret < 0)
0077         return ret;
0078 
0079     return mt7615_efuse_init(dev, addr);
0080 }
0081 
0082 static int mt7615_check_eeprom(struct mt76_dev *dev)
0083 {
0084     u16 val = get_unaligned_le16(dev->eeprom.data);
0085 
0086     switch (val) {
0087     case 0x7615:
0088     case 0x7622:
0089     case 0x7663:
0090         return 0;
0091     default:
0092         return -EINVAL;
0093     }
0094 }
0095 
0096 static void
0097 mt7615_eeprom_parse_hw_band_cap(struct mt7615_dev *dev)
0098 {
0099     u8 val, *eeprom = dev->mt76.eeprom.data;
0100 
0101     if (is_mt7663(&dev->mt76)) {
0102         /* dual band */
0103         dev->mphy.cap.has_2ghz = true;
0104         dev->mphy.cap.has_5ghz = true;
0105         return;
0106     }
0107 
0108     if (is_mt7622(&dev->mt76)) {
0109         /* 2GHz only */
0110         dev->mphy.cap.has_2ghz = true;
0111         return;
0112     }
0113 
0114     if (is_mt7611(&dev->mt76)) {
0115         /* 5GHz only */
0116         dev->mphy.cap.has_5ghz = true;
0117         return;
0118     }
0119 
0120     val = FIELD_GET(MT_EE_NIC_WIFI_CONF_BAND_SEL,
0121             eeprom[MT_EE_WIFI_CONF]);
0122     switch (val) {
0123     case MT_EE_5GHZ:
0124         dev->mphy.cap.has_5ghz = true;
0125         break;
0126     case MT_EE_2GHZ:
0127         dev->mphy.cap.has_2ghz = true;
0128         break;
0129     case MT_EE_DBDC:
0130         dev->dbdc_support = true;
0131         fallthrough;
0132     default:
0133         dev->mphy.cap.has_2ghz = true;
0134         dev->mphy.cap.has_5ghz = true;
0135         break;
0136     }
0137 }
0138 
0139 static void mt7615_eeprom_parse_hw_cap(struct mt7615_dev *dev)
0140 {
0141     u8 *eeprom = dev->mt76.eeprom.data;
0142     u8 tx_mask, max_nss;
0143 
0144     mt7615_eeprom_parse_hw_band_cap(dev);
0145 
0146     if (is_mt7663(&dev->mt76)) {
0147         max_nss = 2;
0148         tx_mask = FIELD_GET(MT_EE_HW_CONF1_TX_MASK,
0149                     eeprom[MT7663_EE_HW_CONF1]);
0150     } else {
0151         u32 val;
0152 
0153         /* read tx-rx mask from eeprom */
0154         val = mt76_rr(dev, MT_TOP_STRAP_STA);
0155         max_nss = val & MT_TOP_3NSS ? 3 : 4;
0156 
0157         tx_mask =  FIELD_GET(MT_EE_NIC_CONF_TX_MASK,
0158                      eeprom[MT_EE_NIC_CONF_0]);
0159     }
0160     if (!tx_mask || tx_mask > max_nss)
0161         tx_mask = max_nss;
0162 
0163     dev->chainmask = BIT(tx_mask) - 1;
0164     dev->mphy.antenna_mask = dev->chainmask;
0165     dev->mphy.chainmask = dev->chainmask;
0166 }
0167 
0168 static int mt7663_eeprom_get_target_power_index(struct mt7615_dev *dev,
0169                         struct ieee80211_channel *chan,
0170                         u8 chain_idx)
0171 {
0172     int index, group;
0173 
0174     if (chain_idx > 1)
0175         return -EINVAL;
0176 
0177     if (chan->band == NL80211_BAND_2GHZ)
0178         return MT7663_EE_TX0_2G_TARGET_POWER + (chain_idx << 4);
0179 
0180     group = mt7615_get_channel_group(chan->hw_value);
0181     if (chain_idx == 1)
0182         index = MT7663_EE_TX1_5G_G0_TARGET_POWER;
0183     else
0184         index = MT7663_EE_TX0_5G_G0_TARGET_POWER;
0185 
0186     return index + group * 3;
0187 }
0188 
0189 int mt7615_eeprom_get_target_power_index(struct mt7615_dev *dev,
0190                      struct ieee80211_channel *chan,
0191                      u8 chain_idx)
0192 {
0193     int index;
0194 
0195     if (is_mt7663(&dev->mt76))
0196         return mt7663_eeprom_get_target_power_index(dev, chan,
0197                                 chain_idx);
0198 
0199     if (chain_idx > 3)
0200         return -EINVAL;
0201 
0202     /* TSSI disabled */
0203     if (mt7615_ext_pa_enabled(dev, chan->band)) {
0204         if (chan->band == NL80211_BAND_2GHZ)
0205             return MT_EE_EXT_PA_2G_TARGET_POWER;
0206         else
0207             return MT_EE_EXT_PA_5G_TARGET_POWER;
0208     }
0209 
0210     /* TSSI enabled */
0211     if (chan->band == NL80211_BAND_2GHZ) {
0212         index = MT_EE_TX0_2G_TARGET_POWER + chain_idx * 6;
0213     } else {
0214         int group = mt7615_get_channel_group(chan->hw_value);
0215 
0216         switch (chain_idx) {
0217         case 1:
0218             index = MT_EE_TX1_5G_G0_TARGET_POWER;
0219             break;
0220         case 2:
0221             index = MT_EE_TX2_5G_G0_TARGET_POWER;
0222             break;
0223         case 3:
0224             index = MT_EE_TX3_5G_G0_TARGET_POWER;
0225             break;
0226         case 0:
0227         default:
0228             index = MT_EE_TX0_5G_G0_TARGET_POWER;
0229             break;
0230         }
0231         index += 5 * group;
0232     }
0233 
0234     return index;
0235 }
0236 
0237 int mt7615_eeprom_get_power_delta_index(struct mt7615_dev *dev,
0238                     enum nl80211_band band)
0239 {
0240     /* assume the first rate has the highest power offset */
0241     if (is_mt7663(&dev->mt76)) {
0242         if (band == NL80211_BAND_2GHZ)
0243             return MT_EE_TX0_5G_G0_TARGET_POWER;
0244         else
0245             return MT7663_EE_5G_RATE_POWER;
0246     }
0247 
0248     if (band == NL80211_BAND_2GHZ)
0249         return MT_EE_2G_RATE_POWER;
0250     else
0251         return MT_EE_5G_RATE_POWER;
0252 }
0253 
0254 static void mt7615_apply_cal_free_data(struct mt7615_dev *dev)
0255 {
0256     static const u16 ical[] = {
0257         0x53, 0x54, 0x55, 0x56, 0x57, 0x5c, 0x5d, 0x62, 0x63, 0x68,
0258         0x69, 0x6e, 0x6f, 0x73, 0x74, 0x78, 0x79, 0x82, 0x83, 0x87,
0259         0x88, 0x8c, 0x8d, 0x91, 0x92, 0x96, 0x97, 0x9b, 0x9c, 0xa0,
0260         0xa1, 0xaa, 0xab, 0xaf, 0xb0, 0xb4, 0xb5, 0xb9, 0xba, 0xf4,
0261         0xf7, 0xff,
0262         0x140, 0x141, 0x145, 0x146, 0x14a, 0x14b, 0x154, 0x155, 0x159,
0263         0x15a, 0x15e, 0x15f, 0x163, 0x164, 0x168, 0x169, 0x16d, 0x16e,
0264         0x172, 0x173, 0x17c, 0x17d, 0x181, 0x182, 0x186, 0x187, 0x18b,
0265         0x18c
0266     };
0267     static const u16 ical_nocheck[] = {
0268         0x110, 0x111, 0x112, 0x113, 0x114, 0x115, 0x116, 0x117, 0x118,
0269         0x1b5, 0x1b6, 0x1b7, 0x3ac, 0x3ad, 0x3ae, 0x3af, 0x3b0, 0x3b1,
0270         0x3b2
0271     };
0272     u8 *eeprom = dev->mt76.eeprom.data;
0273     u8 *otp = dev->mt76.otp.data;
0274     int i;
0275 
0276     if (!otp)
0277         return;
0278 
0279     for (i = 0; i < ARRAY_SIZE(ical); i++)
0280         if (!otp[ical[i]])
0281             return;
0282 
0283     for (i = 0; i < ARRAY_SIZE(ical); i++)
0284         eeprom[ical[i]] = otp[ical[i]];
0285 
0286     for (i = 0; i < ARRAY_SIZE(ical_nocheck); i++)
0287         eeprom[ical_nocheck[i]] = otp[ical_nocheck[i]];
0288 }
0289 
0290 static void mt7622_apply_cal_free_data(struct mt7615_dev *dev)
0291 {
0292     static const u16 ical[] = {
0293         0x53, 0x54, 0x55, 0x56, 0xf4, 0xf7, 0x144, 0x156, 0x15b
0294     };
0295     u8 *eeprom = dev->mt76.eeprom.data;
0296     u8 *otp = dev->mt76.otp.data;
0297     int i;
0298 
0299     if (!otp)
0300         return;
0301 
0302     for (i = 0; i < ARRAY_SIZE(ical); i++) {
0303         if (!otp[ical[i]])
0304             continue;
0305 
0306         eeprom[ical[i]] = otp[ical[i]];
0307     }
0308 }
0309 
0310 static void mt7615_cal_free_data(struct mt7615_dev *dev)
0311 {
0312     struct device_node *np = dev->mt76.dev->of_node;
0313 
0314     if (!np || !of_property_read_bool(np, "mediatek,eeprom-merge-otp"))
0315         return;
0316 
0317     switch (mt76_chip(&dev->mt76)) {
0318     case 0x7622:
0319         mt7622_apply_cal_free_data(dev);
0320         break;
0321     case 0x7615:
0322     case 0x7611:
0323         mt7615_apply_cal_free_data(dev);
0324         break;
0325     }
0326 }
0327 
0328 int mt7615_eeprom_init(struct mt7615_dev *dev, u32 addr)
0329 {
0330     int ret;
0331 
0332     ret = mt7615_eeprom_load(dev, addr);
0333     if (ret < 0)
0334         return ret;
0335 
0336     ret = mt7615_check_eeprom(&dev->mt76);
0337     if (ret && dev->mt76.otp.data) {
0338         memcpy(dev->mt76.eeprom.data, dev->mt76.otp.data,
0339                MT7615_EEPROM_SIZE);
0340     } else {
0341         dev->flash_eeprom = true;
0342         mt7615_cal_free_data(dev);
0343     }
0344 
0345     mt7615_eeprom_parse_hw_cap(dev);
0346     memcpy(dev->mphy.macaddr, dev->mt76.eeprom.data + MT_EE_MAC_ADDR,
0347            ETH_ALEN);
0348 
0349     mt76_eeprom_override(&dev->mphy);
0350 
0351     return 0;
0352 }
0353 EXPORT_SYMBOL_GPL(mt7615_eeprom_init);