Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: ISC
0002 /*
0003  * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
0004  */
0005 
0006 #include <linux/module.h>
0007 #include <linux/of.h>
0008 #include <asm/unaligned.h>
0009 #include "mt76x2.h"
0010 #include "eeprom.h"
0011 
0012 #define EE_FIELD(_name, _value) [MT_EE_##_name] = (_value) | 1
0013 
0014 static int
0015 mt76x2_eeprom_get_macaddr(struct mt76x02_dev *dev)
0016 {
0017     void *src = dev->mt76.eeprom.data + MT_EE_MAC_ADDR;
0018 
0019     memcpy(dev->mphy.macaddr, src, ETH_ALEN);
0020     return 0;
0021 }
0022 
0023 static bool
0024 mt76x2_has_cal_free_data(struct mt76x02_dev *dev, u8 *efuse)
0025 {
0026     u16 *efuse_w = (u16 *)efuse;
0027 
0028     if (efuse_w[MT_EE_NIC_CONF_0] != 0)
0029         return false;
0030 
0031     if (efuse_w[MT_EE_XTAL_TRIM_1] == 0xffff)
0032         return false;
0033 
0034     if (efuse_w[MT_EE_TX_POWER_DELTA_BW40] != 0)
0035         return false;
0036 
0037     if (efuse_w[MT_EE_TX_POWER_0_START_2G] == 0xffff)
0038         return false;
0039 
0040     if (efuse_w[MT_EE_TX_POWER_0_GRP3_TX_POWER_DELTA] != 0)
0041         return false;
0042 
0043     if (efuse_w[MT_EE_TX_POWER_0_GRP4_TSSI_SLOPE] == 0xffff)
0044         return false;
0045 
0046     return true;
0047 }
0048 
0049 static void
0050 mt76x2_apply_cal_free_data(struct mt76x02_dev *dev, u8 *efuse)
0051 {
0052 #define GROUP_5G(_id)                              \
0053     MT_EE_TX_POWER_0_START_5G + MT_TX_POWER_GROUP_SIZE_5G * (_id),     \
0054     MT_EE_TX_POWER_0_START_5G + MT_TX_POWER_GROUP_SIZE_5G * (_id) + 1, \
0055     MT_EE_TX_POWER_1_START_5G + MT_TX_POWER_GROUP_SIZE_5G * (_id),     \
0056     MT_EE_TX_POWER_1_START_5G + MT_TX_POWER_GROUP_SIZE_5G * (_id) + 1
0057 
0058     static const u8 cal_free_bytes[] = {
0059         MT_EE_XTAL_TRIM_1,
0060         MT_EE_TX_POWER_EXT_PA_5G + 1,
0061         MT_EE_TX_POWER_0_START_2G,
0062         MT_EE_TX_POWER_0_START_2G + 1,
0063         MT_EE_TX_POWER_1_START_2G,
0064         MT_EE_TX_POWER_1_START_2G + 1,
0065         GROUP_5G(0),
0066         GROUP_5G(1),
0067         GROUP_5G(2),
0068         GROUP_5G(3),
0069         GROUP_5G(4),
0070         GROUP_5G(5),
0071         MT_EE_RF_2G_TSSI_OFF_TXPOWER,
0072         MT_EE_RF_2G_RX_HIGH_GAIN + 1,
0073         MT_EE_RF_5G_GRP0_1_RX_HIGH_GAIN,
0074         MT_EE_RF_5G_GRP0_1_RX_HIGH_GAIN + 1,
0075         MT_EE_RF_5G_GRP2_3_RX_HIGH_GAIN,
0076         MT_EE_RF_5G_GRP2_3_RX_HIGH_GAIN + 1,
0077         MT_EE_RF_5G_GRP4_5_RX_HIGH_GAIN,
0078         MT_EE_RF_5G_GRP4_5_RX_HIGH_GAIN + 1,
0079     };
0080     struct device_node *np = dev->mt76.dev->of_node;
0081     u8 *eeprom = dev->mt76.eeprom.data;
0082     u8 prev_grp0[4] = {
0083         eeprom[MT_EE_TX_POWER_0_START_5G],
0084         eeprom[MT_EE_TX_POWER_0_START_5G + 1],
0085         eeprom[MT_EE_TX_POWER_1_START_5G],
0086         eeprom[MT_EE_TX_POWER_1_START_5G + 1]
0087     };
0088     u16 val;
0089     int i;
0090 
0091     if (!np || !of_property_read_bool(np, "mediatek,eeprom-merge-otp"))
0092         return;
0093 
0094     if (!mt76x2_has_cal_free_data(dev, efuse))
0095         return;
0096 
0097     for (i = 0; i < ARRAY_SIZE(cal_free_bytes); i++) {
0098         int offset = cal_free_bytes[i];
0099 
0100         eeprom[offset] = efuse[offset];
0101     }
0102 
0103     if (!(efuse[MT_EE_TX_POWER_0_START_5G] |
0104           efuse[MT_EE_TX_POWER_0_START_5G + 1]))
0105         memcpy(eeprom + MT_EE_TX_POWER_0_START_5G, prev_grp0, 2);
0106     if (!(efuse[MT_EE_TX_POWER_1_START_5G] |
0107           efuse[MT_EE_TX_POWER_1_START_5G + 1]))
0108         memcpy(eeprom + MT_EE_TX_POWER_1_START_5G, prev_grp0 + 2, 2);
0109 
0110     val = get_unaligned_le16(efuse + MT_EE_BT_RCAL_RESULT);
0111     if (val != 0xffff)
0112         eeprom[MT_EE_BT_RCAL_RESULT] = val & 0xff;
0113 
0114     val = get_unaligned_le16(efuse + MT_EE_BT_VCDL_CALIBRATION);
0115     if (val != 0xffff)
0116         eeprom[MT_EE_BT_VCDL_CALIBRATION + 1] = val >> 8;
0117 
0118     val = get_unaligned_le16(efuse + MT_EE_BT_PMUCFG);
0119     if (val != 0xffff)
0120         eeprom[MT_EE_BT_PMUCFG] = val & 0xff;
0121 }
0122 
0123 static int mt76x2_check_eeprom(struct mt76x02_dev *dev)
0124 {
0125     u16 val = get_unaligned_le16(dev->mt76.eeprom.data);
0126 
0127     if (!val)
0128         val = get_unaligned_le16(dev->mt76.eeprom.data + MT_EE_PCI_ID);
0129 
0130     switch (val) {
0131     case 0x7662:
0132     case 0x7612:
0133         return 0;
0134     default:
0135         dev_err(dev->mt76.dev, "EEPROM data check failed: %04x\n", val);
0136         return -EINVAL;
0137     }
0138 }
0139 
0140 static int
0141 mt76x2_eeprom_load(struct mt76x02_dev *dev)
0142 {
0143     void *efuse;
0144     bool found;
0145     int ret;
0146 
0147     ret = mt76_eeprom_init(&dev->mt76, MT7662_EEPROM_SIZE);
0148     if (ret < 0)
0149         return ret;
0150 
0151     found = ret;
0152     if (found)
0153         found = !mt76x2_check_eeprom(dev);
0154 
0155     dev->mt76.otp.data = devm_kzalloc(dev->mt76.dev, MT7662_EEPROM_SIZE,
0156                       GFP_KERNEL);
0157     dev->mt76.otp.size = MT7662_EEPROM_SIZE;
0158     if (!dev->mt76.otp.data)
0159         return -ENOMEM;
0160 
0161     efuse = dev->mt76.otp.data;
0162 
0163     if (mt76x02_get_efuse_data(dev, 0, efuse, MT7662_EEPROM_SIZE,
0164                    MT_EE_READ))
0165         goto out;
0166 
0167     if (found) {
0168         mt76x2_apply_cal_free_data(dev, efuse);
0169     } else {
0170         /* FIXME: check if efuse data is complete */
0171         found = true;
0172         memcpy(dev->mt76.eeprom.data, efuse, MT7662_EEPROM_SIZE);
0173     }
0174 
0175 out:
0176     if (!found)
0177         return -ENOENT;
0178 
0179     return 0;
0180 }
0181 
0182 static void
0183 mt76x2_set_rx_gain_group(struct mt76x02_dev *dev, u8 val)
0184 {
0185     s8 *dest = dev->cal.rx.high_gain;
0186 
0187     if (!mt76x02_field_valid(val)) {
0188         dest[0] = 0;
0189         dest[1] = 0;
0190         return;
0191     }
0192 
0193     dest[0] = mt76x02_sign_extend(val, 4);
0194     dest[1] = mt76x02_sign_extend(val >> 4, 4);
0195 }
0196 
0197 static void
0198 mt76x2_set_rssi_offset(struct mt76x02_dev *dev, int chain, u8 val)
0199 {
0200     s8 *dest = dev->cal.rx.rssi_offset;
0201 
0202     if (!mt76x02_field_valid(val)) {
0203         dest[chain] = 0;
0204         return;
0205     }
0206 
0207     dest[chain] = mt76x02_sign_extend_optional(val, 7);
0208 }
0209 
0210 static enum mt76x2_cal_channel_group
0211 mt76x2_get_cal_channel_group(int channel)
0212 {
0213     if (channel >= 184 && channel <= 196)
0214         return MT_CH_5G_JAPAN;
0215     if (channel <= 48)
0216         return MT_CH_5G_UNII_1;
0217     if (channel <= 64)
0218         return MT_CH_5G_UNII_2;
0219     if (channel <= 114)
0220         return MT_CH_5G_UNII_2E_1;
0221     if (channel <= 144)
0222         return MT_CH_5G_UNII_2E_2;
0223     return MT_CH_5G_UNII_3;
0224 }
0225 
0226 static u8
0227 mt76x2_get_5g_rx_gain(struct mt76x02_dev *dev, u8 channel)
0228 {
0229     enum mt76x2_cal_channel_group group;
0230 
0231     group = mt76x2_get_cal_channel_group(channel);
0232     switch (group) {
0233     case MT_CH_5G_JAPAN:
0234         return mt76x02_eeprom_get(dev,
0235                       MT_EE_RF_5G_GRP0_1_RX_HIGH_GAIN);
0236     case MT_CH_5G_UNII_1:
0237         return mt76x02_eeprom_get(dev,
0238                       MT_EE_RF_5G_GRP0_1_RX_HIGH_GAIN) >> 8;
0239     case MT_CH_5G_UNII_2:
0240         return mt76x02_eeprom_get(dev,
0241                       MT_EE_RF_5G_GRP2_3_RX_HIGH_GAIN);
0242     case MT_CH_5G_UNII_2E_1:
0243         return mt76x02_eeprom_get(dev,
0244                       MT_EE_RF_5G_GRP2_3_RX_HIGH_GAIN) >> 8;
0245     case MT_CH_5G_UNII_2E_2:
0246         return mt76x02_eeprom_get(dev,
0247                       MT_EE_RF_5G_GRP4_5_RX_HIGH_GAIN);
0248     default:
0249         return mt76x02_eeprom_get(dev,
0250                       MT_EE_RF_5G_GRP4_5_RX_HIGH_GAIN) >> 8;
0251     }
0252 }
0253 
0254 void mt76x2_read_rx_gain(struct mt76x02_dev *dev)
0255 {
0256     struct ieee80211_channel *chan = dev->mphy.chandef.chan;
0257     int channel = chan->hw_value;
0258     s8 lna_5g[3], lna_2g;
0259     u8 lna;
0260     u16 val;
0261 
0262     if (chan->band == NL80211_BAND_2GHZ)
0263         val = mt76x02_eeprom_get(dev, MT_EE_RF_2G_RX_HIGH_GAIN) >> 8;
0264     else
0265         val = mt76x2_get_5g_rx_gain(dev, channel);
0266 
0267     mt76x2_set_rx_gain_group(dev, val);
0268 
0269     mt76x02_get_rx_gain(dev, chan->band, &val, &lna_2g, lna_5g);
0270     mt76x2_set_rssi_offset(dev, 0, val);
0271     mt76x2_set_rssi_offset(dev, 1, val >> 8);
0272 
0273     dev->cal.rx.mcu_gain =  (lna_2g & 0xff);
0274     dev->cal.rx.mcu_gain |= (lna_5g[0] & 0xff) << 8;
0275     dev->cal.rx.mcu_gain |= (lna_5g[1] & 0xff) << 16;
0276     dev->cal.rx.mcu_gain |= (lna_5g[2] & 0xff) << 24;
0277 
0278     lna = mt76x02_get_lna_gain(dev, &lna_2g, lna_5g, chan);
0279     dev->cal.rx.lna_gain = mt76x02_sign_extend(lna, 8);
0280 }
0281 EXPORT_SYMBOL_GPL(mt76x2_read_rx_gain);
0282 
0283 void mt76x2_get_rate_power(struct mt76x02_dev *dev, struct mt76_rate_power *t,
0284                struct ieee80211_channel *chan)
0285 {
0286     bool is_5ghz;
0287     u16 val;
0288 
0289     is_5ghz = chan->band == NL80211_BAND_5GHZ;
0290 
0291     memset(t, 0, sizeof(*t));
0292 
0293     val = mt76x02_eeprom_get(dev, MT_EE_TX_POWER_CCK);
0294     t->cck[0] = t->cck[1] = mt76x02_rate_power_val(val);
0295     t->cck[2] = t->cck[3] = mt76x02_rate_power_val(val >> 8);
0296 
0297     if (is_5ghz)
0298         val = mt76x02_eeprom_get(dev, MT_EE_TX_POWER_OFDM_5G_6M);
0299     else
0300         val = mt76x02_eeprom_get(dev, MT_EE_TX_POWER_OFDM_2G_6M);
0301     t->ofdm[0] = t->ofdm[1] = mt76x02_rate_power_val(val);
0302     t->ofdm[2] = t->ofdm[3] = mt76x02_rate_power_val(val >> 8);
0303 
0304     if (is_5ghz)
0305         val = mt76x02_eeprom_get(dev, MT_EE_TX_POWER_OFDM_5G_24M);
0306     else
0307         val = mt76x02_eeprom_get(dev, MT_EE_TX_POWER_OFDM_2G_24M);
0308     t->ofdm[4] = t->ofdm[5] = mt76x02_rate_power_val(val);
0309     t->ofdm[6] = t->ofdm[7] = mt76x02_rate_power_val(val >> 8);
0310 
0311     val = mt76x02_eeprom_get(dev, MT_EE_TX_POWER_HT_MCS0);
0312     t->ht[0] = t->ht[1] = mt76x02_rate_power_val(val);
0313     t->ht[2] = t->ht[3] = mt76x02_rate_power_val(val >> 8);
0314 
0315     val = mt76x02_eeprom_get(dev, MT_EE_TX_POWER_HT_MCS4);
0316     t->ht[4] = t->ht[5] = mt76x02_rate_power_val(val);
0317     t->ht[6] = t->ht[7] = mt76x02_rate_power_val(val >> 8);
0318 
0319     val = mt76x02_eeprom_get(dev, MT_EE_TX_POWER_HT_MCS8);
0320     t->ht[8] = t->ht[9] = mt76x02_rate_power_val(val);
0321     t->ht[10] = t->ht[11] = mt76x02_rate_power_val(val >> 8);
0322 
0323     val = mt76x02_eeprom_get(dev, MT_EE_TX_POWER_HT_MCS12);
0324     t->ht[12] = t->ht[13] = mt76x02_rate_power_val(val);
0325     t->ht[14] = t->ht[15] = mt76x02_rate_power_val(val >> 8);
0326 
0327     val = mt76x02_eeprom_get(dev, MT_EE_TX_POWER_VHT_MCS0);
0328     t->vht[0] = t->vht[1] = mt76x02_rate_power_val(val);
0329     t->vht[2] = t->vht[3] = mt76x02_rate_power_val(val >> 8);
0330 
0331     val = mt76x02_eeprom_get(dev, MT_EE_TX_POWER_VHT_MCS4);
0332     t->vht[4] = t->vht[5] = mt76x02_rate_power_val(val);
0333     t->vht[6] = t->vht[7] = mt76x02_rate_power_val(val >> 8);
0334 
0335     val = mt76x02_eeprom_get(dev, MT_EE_TX_POWER_VHT_MCS8);
0336     if (!is_5ghz)
0337         val >>= 8;
0338     t->vht[8] = t->vht[9] = mt76x02_rate_power_val(val >> 8);
0339 
0340     memcpy(t->stbc, t->ht, sizeof(t->stbc[0]) * 8);
0341     t->stbc[8] = t->vht[8];
0342     t->stbc[9] = t->vht[9];
0343 }
0344 EXPORT_SYMBOL_GPL(mt76x2_get_rate_power);
0345 
0346 static void
0347 mt76x2_get_power_info_2g(struct mt76x02_dev *dev,
0348              struct mt76x2_tx_power_info *t,
0349              struct ieee80211_channel *chan,
0350              int chain, int offset)
0351 {
0352     int channel = chan->hw_value;
0353     int delta_idx;
0354     u8 data[6];
0355     u16 val;
0356 
0357     if (channel < 6)
0358         delta_idx = 3;
0359     else if (channel < 11)
0360         delta_idx = 4;
0361     else
0362         delta_idx = 5;
0363 
0364     mt76x02_eeprom_copy(dev, offset, data, sizeof(data));
0365 
0366     t->chain[chain].tssi_slope = data[0];
0367     t->chain[chain].tssi_offset = data[1];
0368     t->chain[chain].target_power = data[2];
0369     t->chain[chain].delta =
0370         mt76x02_sign_extend_optional(data[delta_idx], 7);
0371 
0372     val = mt76x02_eeprom_get(dev, MT_EE_RF_2G_TSSI_OFF_TXPOWER);
0373     t->target_power = val >> 8;
0374 }
0375 
0376 static void
0377 mt76x2_get_power_info_5g(struct mt76x02_dev *dev,
0378              struct mt76x2_tx_power_info *t,
0379              struct ieee80211_channel *chan,
0380              int chain, int offset)
0381 {
0382     int channel = chan->hw_value;
0383     enum mt76x2_cal_channel_group group;
0384     int delta_idx;
0385     u16 val;
0386     u8 data[5];
0387 
0388     group = mt76x2_get_cal_channel_group(channel);
0389     offset += group * MT_TX_POWER_GROUP_SIZE_5G;
0390 
0391     if (channel >= 192)
0392         delta_idx = 4;
0393     else if (channel >= 184)
0394         delta_idx = 3;
0395     else if (channel < 44)
0396         delta_idx = 3;
0397     else if (channel < 52)
0398         delta_idx = 4;
0399     else if (channel < 58)
0400         delta_idx = 3;
0401     else if (channel < 98)
0402         delta_idx = 4;
0403     else if (channel < 106)
0404         delta_idx = 3;
0405     else if (channel < 116)
0406         delta_idx = 4;
0407     else if (channel < 130)
0408         delta_idx = 3;
0409     else if (channel < 149)
0410         delta_idx = 4;
0411     else if (channel < 157)
0412         delta_idx = 3;
0413     else
0414         delta_idx = 4;
0415 
0416     mt76x02_eeprom_copy(dev, offset, data, sizeof(data));
0417 
0418     t->chain[chain].tssi_slope = data[0];
0419     t->chain[chain].tssi_offset = data[1];
0420     t->chain[chain].target_power = data[2];
0421     t->chain[chain].delta =
0422         mt76x02_sign_extend_optional(data[delta_idx], 7);
0423 
0424     val = mt76x02_eeprom_get(dev, MT_EE_RF_2G_RX_HIGH_GAIN);
0425     t->target_power = val & 0xff;
0426 }
0427 
0428 void mt76x2_get_power_info(struct mt76x02_dev *dev,
0429                struct mt76x2_tx_power_info *t,
0430                struct ieee80211_channel *chan)
0431 {
0432     u16 bw40, bw80;
0433 
0434     memset(t, 0, sizeof(*t));
0435 
0436     bw40 = mt76x02_eeprom_get(dev, MT_EE_TX_POWER_DELTA_BW40);
0437     bw80 = mt76x02_eeprom_get(dev, MT_EE_TX_POWER_DELTA_BW80);
0438 
0439     if (chan->band == NL80211_BAND_5GHZ) {
0440         bw40 >>= 8;
0441         mt76x2_get_power_info_5g(dev, t, chan, 0,
0442                      MT_EE_TX_POWER_0_START_5G);
0443         mt76x2_get_power_info_5g(dev, t, chan, 1,
0444                      MT_EE_TX_POWER_1_START_5G);
0445     } else {
0446         mt76x2_get_power_info_2g(dev, t, chan, 0,
0447                      MT_EE_TX_POWER_0_START_2G);
0448         mt76x2_get_power_info_2g(dev, t, chan, 1,
0449                      MT_EE_TX_POWER_1_START_2G);
0450     }
0451 
0452     if (mt76x2_tssi_enabled(dev) ||
0453         !mt76x02_field_valid(t->target_power))
0454         t->target_power = t->chain[0].target_power;
0455 
0456     t->delta_bw40 = mt76x02_rate_power_val(bw40);
0457     t->delta_bw80 = mt76x02_rate_power_val(bw80);
0458 }
0459 EXPORT_SYMBOL_GPL(mt76x2_get_power_info);
0460 
0461 int mt76x2_get_temp_comp(struct mt76x02_dev *dev, struct mt76x2_temp_comp *t)
0462 {
0463     enum nl80211_band band = dev->mphy.chandef.chan->band;
0464     u16 val, slope;
0465     u8 bounds;
0466 
0467     memset(t, 0, sizeof(*t));
0468 
0469     if (!mt76x2_temp_tx_alc_enabled(dev))
0470         return -EINVAL;
0471 
0472     if (!mt76x02_ext_pa_enabled(dev, band))
0473         return -EINVAL;
0474 
0475     val = mt76x02_eeprom_get(dev, MT_EE_TX_POWER_EXT_PA_5G) >> 8;
0476     t->temp_25_ref = val & 0x7f;
0477     if (band == NL80211_BAND_5GHZ) {
0478         slope = mt76x02_eeprom_get(dev, MT_EE_RF_TEMP_COMP_SLOPE_5G);
0479         bounds = mt76x02_eeprom_get(dev, MT_EE_TX_POWER_EXT_PA_5G);
0480     } else {
0481         slope = mt76x02_eeprom_get(dev, MT_EE_RF_TEMP_COMP_SLOPE_2G);
0482         bounds = mt76x02_eeprom_get(dev,
0483                         MT_EE_TX_POWER_DELTA_BW80) >> 8;
0484     }
0485 
0486     t->high_slope = slope & 0xff;
0487     t->low_slope = slope >> 8;
0488     t->lower_bound = 0 - (bounds & 0xf);
0489     t->upper_bound = (bounds >> 4) & 0xf;
0490 
0491     return 0;
0492 }
0493 EXPORT_SYMBOL_GPL(mt76x2_get_temp_comp);
0494 
0495 int mt76x2_eeprom_init(struct mt76x02_dev *dev)
0496 {
0497     int ret;
0498 
0499     ret = mt76x2_eeprom_load(dev);
0500     if (ret)
0501         return ret;
0502 
0503     mt76x02_eeprom_parse_hw_cap(dev);
0504     mt76x2_eeprom_get_macaddr(dev);
0505     mt76_eeprom_override(&dev->mphy);
0506     dev->mphy.macaddr[0] &= ~BIT(1);
0507 
0508     return 0;
0509 }
0510 EXPORT_SYMBOL_GPL(mt76x2_eeprom_init);
0511 
0512 MODULE_LICENSE("Dual BSD/GPL");