Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: ISC
0002 /* Copyright (C) 2020 MediaTek Inc. */
0003 
0004 #include <linux/firmware.h>
0005 #include "mt7915.h"
0006 #include "eeprom.h"
0007 
0008 static int mt7915_eeprom_load_precal(struct mt7915_dev *dev)
0009 {
0010     struct mt76_dev *mdev = &dev->mt76;
0011     u8 *eeprom = mdev->eeprom.data;
0012     u32 val = eeprom[MT_EE_DO_PRE_CAL];
0013     u32 offs;
0014 
0015     if (!dev->flash_mode)
0016         return 0;
0017 
0018     if (val != (MT_EE_WIFI_CAL_DPD | MT_EE_WIFI_CAL_GROUP))
0019         return 0;
0020 
0021     val = MT_EE_CAL_GROUP_SIZE + MT_EE_CAL_DPD_SIZE;
0022     dev->cal = devm_kzalloc(mdev->dev, val, GFP_KERNEL);
0023     if (!dev->cal)
0024         return -ENOMEM;
0025 
0026     offs = is_mt7915(&dev->mt76) ? MT_EE_PRECAL : MT_EE_PRECAL_V2;
0027 
0028     return mt76_get_of_eeprom(mdev, dev->cal, offs, val);
0029 }
0030 
0031 static int mt7915_check_eeprom(struct mt7915_dev *dev)
0032 {
0033     u8 *eeprom = dev->mt76.eeprom.data;
0034     u16 val = get_unaligned_le16(eeprom);
0035 
0036     switch (val) {
0037     case 0x7915:
0038     case 0x7916:
0039     case 0x7986:
0040         return 0;
0041     default:
0042         return -EINVAL;
0043     }
0044 }
0045 
0046 static char *mt7915_eeprom_name(struct mt7915_dev *dev)
0047 {
0048     switch (mt76_chip(&dev->mt76)) {
0049     case 0x7915:
0050         return dev->dbdc_support ?
0051                MT7915_EEPROM_DEFAULT_DBDC : MT7915_EEPROM_DEFAULT;
0052     case 0x7986:
0053         switch (mt7915_check_adie(dev, true)) {
0054         case MT7976_ONE_ADIE_DBDC:
0055             return MT7986_EEPROM_MT7976_DEFAULT_DBDC;
0056         case MT7975_ONE_ADIE:
0057             return MT7986_EEPROM_MT7975_DEFAULT;
0058         case MT7976_ONE_ADIE:
0059             return MT7986_EEPROM_MT7976_DEFAULT;
0060         case MT7975_DUAL_ADIE:
0061             return MT7986_EEPROM_MT7975_DUAL_DEFAULT;
0062         case MT7976_DUAL_ADIE:
0063             return MT7986_EEPROM_MT7976_DUAL_DEFAULT;
0064         default:
0065             break;
0066         }
0067         return NULL;
0068     default:
0069         return MT7916_EEPROM_DEFAULT;
0070     }
0071 }
0072 
0073 static int
0074 mt7915_eeprom_load_default(struct mt7915_dev *dev)
0075 {
0076     u8 *eeprom = dev->mt76.eeprom.data;
0077     const struct firmware *fw = NULL;
0078     int ret;
0079 
0080     ret = request_firmware(&fw, mt7915_eeprom_name(dev), dev->mt76.dev);
0081     if (ret)
0082         return ret;
0083 
0084     if (!fw || !fw->data) {
0085         dev_err(dev->mt76.dev, "Invalid default bin\n");
0086         ret = -EINVAL;
0087         goto out;
0088     }
0089 
0090     memcpy(eeprom, fw->data, mt7915_eeprom_size(dev));
0091     dev->flash_mode = true;
0092 
0093 out:
0094     release_firmware(fw);
0095 
0096     return ret;
0097 }
0098 
0099 static int mt7915_eeprom_load(struct mt7915_dev *dev)
0100 {
0101     int ret;
0102     u16 eeprom_size = mt7915_eeprom_size(dev);
0103 
0104     ret = mt76_eeprom_init(&dev->mt76, eeprom_size);
0105     if (ret < 0)
0106         return ret;
0107 
0108     if (ret) {
0109         dev->flash_mode = true;
0110     } else {
0111         u8 free_block_num;
0112         u32 block_num, i;
0113 
0114         mt7915_mcu_get_eeprom_free_block(dev, &free_block_num);
0115         /* efuse info not enough */
0116         if (free_block_num >= 29)
0117             return -EINVAL;
0118 
0119         /* read eeprom data from efuse */
0120         block_num = DIV_ROUND_UP(eeprom_size,
0121                      MT7915_EEPROM_BLOCK_SIZE);
0122         for (i = 0; i < block_num; i++)
0123             mt7915_mcu_get_eeprom(dev,
0124                           i * MT7915_EEPROM_BLOCK_SIZE);
0125     }
0126 
0127     return mt7915_check_eeprom(dev);
0128 }
0129 
0130 static void mt7915_eeprom_parse_band_config(struct mt7915_phy *phy)
0131 {
0132     struct mt7915_dev *dev = phy->dev;
0133     u8 *eeprom = dev->mt76.eeprom.data;
0134     u32 val;
0135 
0136     val = eeprom[MT_EE_WIFI_CONF + phy->band_idx];
0137     val = FIELD_GET(MT_EE_WIFI_CONF0_BAND_SEL, val);
0138 
0139     if (!is_mt7915(&dev->mt76)) {
0140         switch (val) {
0141         case MT_EE_V2_BAND_SEL_5GHZ:
0142             phy->mt76->cap.has_5ghz = true;
0143             return;
0144         case MT_EE_V2_BAND_SEL_6GHZ:
0145             phy->mt76->cap.has_6ghz = true;
0146             return;
0147         case MT_EE_V2_BAND_SEL_5GHZ_6GHZ:
0148             phy->mt76->cap.has_5ghz = true;
0149             phy->mt76->cap.has_6ghz = true;
0150             return;
0151         default:
0152             phy->mt76->cap.has_2ghz = true;
0153             return;
0154         }
0155     } else if (val == MT_EE_BAND_SEL_DEFAULT && dev->dbdc_support) {
0156         val = phy->band_idx ? MT_EE_BAND_SEL_5GHZ : MT_EE_BAND_SEL_2GHZ;
0157     }
0158 
0159     switch (val) {
0160     case MT_EE_BAND_SEL_5GHZ:
0161         phy->mt76->cap.has_5ghz = true;
0162         break;
0163     case MT_EE_BAND_SEL_2GHZ:
0164         phy->mt76->cap.has_2ghz = true;
0165         break;
0166     default:
0167         phy->mt76->cap.has_2ghz = true;
0168         phy->mt76->cap.has_5ghz = true;
0169         break;
0170     }
0171 }
0172 
0173 void mt7915_eeprom_parse_hw_cap(struct mt7915_dev *dev,
0174                 struct mt7915_phy *phy)
0175 {
0176     u8 nss, nss_band, nss_band_max, *eeprom = dev->mt76.eeprom.data;
0177     struct mt76_phy *mphy = phy->mt76;
0178     bool ext_phy = phy != &dev->phy;
0179 
0180     mt7915_eeprom_parse_band_config(phy);
0181 
0182     /* read tx/rx mask from eeprom */
0183     if (is_mt7915(&dev->mt76)) {
0184         nss = FIELD_GET(MT_EE_WIFI_CONF0_TX_PATH,
0185                 eeprom[MT_EE_WIFI_CONF]);
0186     } else {
0187         nss = FIELD_GET(MT_EE_WIFI_CONF0_TX_PATH,
0188                 eeprom[MT_EE_WIFI_CONF + phy->band_idx]);
0189     }
0190 
0191     if (!nss || nss > 4)
0192         nss = 4;
0193 
0194     /* read tx/rx stream */
0195     nss_band = nss;
0196 
0197     if (dev->dbdc_support) {
0198         if (is_mt7915(&dev->mt76)) {
0199             nss_band = FIELD_GET(MT_EE_WIFI_CONF3_TX_PATH_B0,
0200                          eeprom[MT_EE_WIFI_CONF + 3]);
0201             if (phy->band_idx)
0202                 nss_band = FIELD_GET(MT_EE_WIFI_CONF3_TX_PATH_B1,
0203                              eeprom[MT_EE_WIFI_CONF + 3]);
0204         } else {
0205             nss_band = FIELD_GET(MT_EE_WIFI_CONF_STREAM_NUM,
0206                          eeprom[MT_EE_WIFI_CONF + 2 + phy->band_idx]);
0207         }
0208 
0209         nss_band_max = is_mt7986(&dev->mt76) ?
0210                    MT_EE_NSS_MAX_DBDC_MA7986 : MT_EE_NSS_MAX_DBDC_MA7915;
0211     } else {
0212         nss_band_max = is_mt7986(&dev->mt76) ?
0213                    MT_EE_NSS_MAX_MA7986 : MT_EE_NSS_MAX_MA7915;
0214     }
0215 
0216     if (!nss_band || nss_band > nss_band_max)
0217         nss_band = nss_band_max;
0218 
0219     if (nss_band > nss) {
0220         dev_warn(dev->mt76.dev,
0221              "nss mismatch, nss(%d) nss_band(%d) band(%d) ext_phy(%d)\n",
0222              nss, nss_band, phy->band_idx, ext_phy);
0223         nss = nss_band;
0224     }
0225 
0226     mphy->chainmask = BIT(nss) - 1;
0227     if (ext_phy)
0228         mphy->chainmask <<= dev->chainshift;
0229     mphy->antenna_mask = BIT(nss_band) - 1;
0230     dev->chainmask |= mphy->chainmask;
0231     dev->chainshift = hweight8(dev->mphy.chainmask);
0232 }
0233 
0234 int mt7915_eeprom_init(struct mt7915_dev *dev)
0235 {
0236     int ret;
0237 
0238     ret = mt7915_eeprom_load(dev);
0239     if (ret < 0) {
0240         if (ret != -EINVAL)
0241             return ret;
0242 
0243         dev_warn(dev->mt76.dev, "eeprom load fail, use default bin\n");
0244         ret = mt7915_eeprom_load_default(dev);
0245         if (ret)
0246             return ret;
0247     }
0248 
0249     ret = mt7915_eeprom_load_precal(dev);
0250     if (ret)
0251         return ret;
0252 
0253     mt7915_eeprom_parse_hw_cap(dev, &dev->phy);
0254     memcpy(dev->mphy.macaddr, dev->mt76.eeprom.data + MT_EE_MAC_ADDR,
0255            ETH_ALEN);
0256 
0257     mt76_eeprom_override(&dev->mphy);
0258 
0259     return 0;
0260 }
0261 
0262 int mt7915_eeprom_get_target_power(struct mt7915_dev *dev,
0263                    struct ieee80211_channel *chan,
0264                    u8 chain_idx)
0265 {
0266     u8 *eeprom = dev->mt76.eeprom.data;
0267     int index, target_power;
0268     bool tssi_on, is_7976;
0269 
0270     if (chain_idx > 3)
0271         return -EINVAL;
0272 
0273     tssi_on = mt7915_tssi_enabled(dev, chan->band);
0274     is_7976 = mt7915_check_adie(dev, false) || is_mt7916(&dev->mt76);
0275 
0276     if (chan->band == NL80211_BAND_2GHZ) {
0277         if (is_7976) {
0278             index = MT_EE_TX0_POWER_2G_V2 + chain_idx;
0279             target_power = eeprom[index];
0280         } else {
0281             index = MT_EE_TX0_POWER_2G + chain_idx * 3;
0282             target_power = eeprom[index];
0283 
0284             if (!tssi_on)
0285                 target_power += eeprom[index + 1];
0286         }
0287     } else if (chan->band == NL80211_BAND_5GHZ) {
0288         int group = mt7915_get_channel_group_5g(chan->hw_value, is_7976);
0289 
0290         if (is_7976) {
0291             index = MT_EE_TX0_POWER_5G_V2 + chain_idx * 5;
0292             target_power = eeprom[index + group];
0293         } else {
0294             index = MT_EE_TX0_POWER_5G + chain_idx * 12;
0295             target_power = eeprom[index + group];
0296 
0297             if (!tssi_on)
0298                 target_power += eeprom[index + 8];
0299         }
0300     } else {
0301         int group = mt7915_get_channel_group_6g(chan->hw_value);
0302 
0303         index = MT_EE_TX0_POWER_6G_V2 + chain_idx * 8;
0304         target_power = is_7976 ? eeprom[index + group] : 0;
0305     }
0306 
0307     return target_power;
0308 }
0309 
0310 s8 mt7915_eeprom_get_power_delta(struct mt7915_dev *dev, int band)
0311 {
0312     u8 *eeprom = dev->mt76.eeprom.data;
0313     u32 val, offs;
0314     s8 delta;
0315     bool is_7976 = mt7915_check_adie(dev, false) || is_mt7916(&dev->mt76);
0316 
0317     if (band == NL80211_BAND_2GHZ)
0318         offs = is_7976 ? MT_EE_RATE_DELTA_2G_V2 : MT_EE_RATE_DELTA_2G;
0319     else if (band == NL80211_BAND_5GHZ)
0320         offs = is_7976 ? MT_EE_RATE_DELTA_5G_V2 : MT_EE_RATE_DELTA_5G;
0321     else
0322         offs = is_7976 ? MT_EE_RATE_DELTA_6G_V2 : 0;
0323 
0324     val = eeprom[offs];
0325 
0326     if (!offs || !(val & MT_EE_RATE_DELTA_EN))
0327         return 0;
0328 
0329     delta = FIELD_GET(MT_EE_RATE_DELTA_MASK, val);
0330 
0331     return val & MT_EE_RATE_DELTA_SIGN ? delta : -delta;
0332 }
0333 
0334 const u8 mt7915_sku_group_len[] = {
0335     [SKU_CCK] = 4,
0336     [SKU_OFDM] = 8,
0337     [SKU_HT_BW20] = 8,
0338     [SKU_HT_BW40] = 9,
0339     [SKU_VHT_BW20] = 12,
0340     [SKU_VHT_BW40] = 12,
0341     [SKU_VHT_BW80] = 12,
0342     [SKU_VHT_BW160] = 12,
0343     [SKU_HE_RU26] = 12,
0344     [SKU_HE_RU52] = 12,
0345     [SKU_HE_RU106] = 12,
0346     [SKU_HE_RU242] = 12,
0347     [SKU_HE_RU484] = 12,
0348     [SKU_HE_RU996] = 12,
0349     [SKU_HE_RU2x996] = 12
0350 };