root/drivers/net/wireless/mediatek/mt76/mt76x02_eeprom.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. mt76x02_efuse_read
  2. mt76x02_eeprom_copy
  3. mt76x02_get_efuse_data
  4. mt76x02_eeprom_parse_hw_cap
  5. mt76x02_ext_pa_enabled
  6. mt76x02_get_rx_gain
  7. mt76x02_get_lna_gain

   1 // SPDX-License-Identifier: ISC
   2 /*
   3  * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
   4  * Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
   5  */
   6 
   7 #include <asm/unaligned.h>
   8 
   9 #include "mt76x02_eeprom.h"
  10 
  11 static int
  12 mt76x02_efuse_read(struct mt76x02_dev *dev, u16 addr, u8 *data,
  13                    enum mt76x02_eeprom_modes mode)
  14 {
  15         u32 val;
  16         int i;
  17 
  18         val = mt76_rr(dev, MT_EFUSE_CTRL);
  19         val &= ~(MT_EFUSE_CTRL_AIN |
  20                  MT_EFUSE_CTRL_MODE);
  21         val |= FIELD_PREP(MT_EFUSE_CTRL_AIN, addr & ~0xf);
  22         val |= FIELD_PREP(MT_EFUSE_CTRL_MODE, mode);
  23         val |= MT_EFUSE_CTRL_KICK;
  24         mt76_wr(dev, MT_EFUSE_CTRL, val);
  25 
  26         if (!mt76_poll_msec(dev, MT_EFUSE_CTRL, MT_EFUSE_CTRL_KICK, 0, 1000))
  27                 return -ETIMEDOUT;
  28 
  29         udelay(2);
  30 
  31         val = mt76_rr(dev, MT_EFUSE_CTRL);
  32         if ((val & MT_EFUSE_CTRL_AOUT) == MT_EFUSE_CTRL_AOUT) {
  33                 memset(data, 0xff, 16);
  34                 return 0;
  35         }
  36 
  37         for (i = 0; i < 4; i++) {
  38                 val = mt76_rr(dev, MT_EFUSE_DATA(i));
  39                 put_unaligned_le32(val, data + 4 * i);
  40         }
  41 
  42         return 0;
  43 }
  44 
  45 int mt76x02_eeprom_copy(struct mt76x02_dev *dev,
  46                         enum mt76x02_eeprom_field field,
  47                         void *dest, int len)
  48 {
  49         if (field + len > dev->mt76.eeprom.size)
  50                 return -1;
  51 
  52         memcpy(dest, dev->mt76.eeprom.data + field, len);
  53         return 0;
  54 }
  55 EXPORT_SYMBOL_GPL(mt76x02_eeprom_copy);
  56 
  57 int mt76x02_get_efuse_data(struct mt76x02_dev *dev, u16 base, void *buf,
  58                            int len, enum mt76x02_eeprom_modes mode)
  59 {
  60         int ret, i;
  61 
  62         for (i = 0; i + 16 <= len; i += 16) {
  63                 ret = mt76x02_efuse_read(dev, base + i, buf + i, mode);
  64                 if (ret)
  65                         return ret;
  66         }
  67 
  68         return 0;
  69 }
  70 EXPORT_SYMBOL_GPL(mt76x02_get_efuse_data);
  71 
  72 void mt76x02_eeprom_parse_hw_cap(struct mt76x02_dev *dev)
  73 {
  74         u16 val = mt76x02_eeprom_get(dev, MT_EE_NIC_CONF_0);
  75 
  76         switch (FIELD_GET(MT_EE_NIC_CONF_0_BOARD_TYPE, val)) {
  77         case BOARD_TYPE_5GHZ:
  78                 dev->mt76.cap.has_5ghz = true;
  79                 break;
  80         case BOARD_TYPE_2GHZ:
  81                 dev->mt76.cap.has_2ghz = true;
  82                 break;
  83         default:
  84                 dev->mt76.cap.has_2ghz = true;
  85                 dev->mt76.cap.has_5ghz = true;
  86                 break;
  87         }
  88 }
  89 EXPORT_SYMBOL_GPL(mt76x02_eeprom_parse_hw_cap);
  90 
  91 bool mt76x02_ext_pa_enabled(struct mt76x02_dev *dev, enum nl80211_band band)
  92 {
  93         u16 conf0 = mt76x02_eeprom_get(dev, MT_EE_NIC_CONF_0);
  94 
  95         if (band == NL80211_BAND_5GHZ)
  96                 return !(conf0 & MT_EE_NIC_CONF_0_PA_INT_5G);
  97         else
  98                 return !(conf0 & MT_EE_NIC_CONF_0_PA_INT_2G);
  99 }
 100 EXPORT_SYMBOL_GPL(mt76x02_ext_pa_enabled);
 101 
 102 void mt76x02_get_rx_gain(struct mt76x02_dev *dev, enum nl80211_band band,
 103                          u16 *rssi_offset, s8 *lna_2g, s8 *lna_5g)
 104 {
 105         u16 val;
 106 
 107         val = mt76x02_eeprom_get(dev, MT_EE_LNA_GAIN);
 108         *lna_2g = val & 0xff;
 109         lna_5g[0] = val >> 8;
 110 
 111         val = mt76x02_eeprom_get(dev, MT_EE_RSSI_OFFSET_2G_1);
 112         lna_5g[1] = val >> 8;
 113 
 114         val = mt76x02_eeprom_get(dev, MT_EE_RSSI_OFFSET_5G_1);
 115         lna_5g[2] = val >> 8;
 116 
 117         if (!mt76x02_field_valid(lna_5g[1]))
 118                 lna_5g[1] = lna_5g[0];
 119 
 120         if (!mt76x02_field_valid(lna_5g[2]))
 121                 lna_5g[2] = lna_5g[0];
 122 
 123         if (band == NL80211_BAND_2GHZ)
 124                 *rssi_offset = mt76x02_eeprom_get(dev, MT_EE_RSSI_OFFSET_2G_0);
 125         else
 126                 *rssi_offset = mt76x02_eeprom_get(dev, MT_EE_RSSI_OFFSET_5G_0);
 127 }
 128 EXPORT_SYMBOL_GPL(mt76x02_get_rx_gain);
 129 
 130 u8 mt76x02_get_lna_gain(struct mt76x02_dev *dev,
 131                         s8 *lna_2g, s8 *lna_5g,
 132                         struct ieee80211_channel *chan)
 133 {
 134         u16 val;
 135         u8 lna;
 136 
 137         val = mt76x02_eeprom_get(dev, MT_EE_NIC_CONF_1);
 138         if (val & MT_EE_NIC_CONF_1_LNA_EXT_2G)
 139                 *lna_2g = 0;
 140         if (val & MT_EE_NIC_CONF_1_LNA_EXT_5G)
 141                 memset(lna_5g, 0, sizeof(s8) * 3);
 142 
 143         if (chan->band == NL80211_BAND_2GHZ)
 144                 lna = *lna_2g;
 145         else if (chan->hw_value <= 64)
 146                 lna = lna_5g[0];
 147         else if (chan->hw_value <= 128)
 148                 lna = lna_5g[1];
 149         else
 150                 lna = lna_5g[2];
 151 
 152         return lna != 0xff ? lna : 0;
 153 }
 154 EXPORT_SYMBOL_GPL(mt76x02_get_lna_gain);

/* [<][>][^][v][top][bottom][index][help] */