summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c')
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c85
1 files changed, 58 insertions, 27 deletions
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c b/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c
index 6aa749b02cc3..0fa539479aa7 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c
@@ -36,27 +36,48 @@ static int mt7915_check_eeprom(struct mt7915_dev *dev)
switch (val) {
case 0x7915:
case 0x7916:
+ case 0x7986:
return 0;
default:
return -EINVAL;
}
}
+static char *mt7915_eeprom_name(struct mt7915_dev *dev)
+{
+ switch (mt76_chip(&dev->mt76)) {
+ case 0x7915:
+ return dev->dbdc_support ?
+ MT7915_EEPROM_DEFAULT_DBDC : MT7915_EEPROM_DEFAULT;
+ case 0x7986:
+ switch (mt7915_check_adie(dev, true)) {
+ case MT7976_ONE_ADIE_DBDC:
+ return MT7986_EEPROM_MT7976_DEFAULT_DBDC;
+ case MT7975_ONE_ADIE:
+ return MT7986_EEPROM_MT7975_DEFAULT;
+ case MT7976_ONE_ADIE:
+ return MT7986_EEPROM_MT7976_DEFAULT;
+ case MT7975_DUAL_ADIE:
+ return MT7986_EEPROM_MT7975_DUAL_DEFAULT;
+ case MT7976_DUAL_ADIE:
+ return MT7986_EEPROM_MT7976_DUAL_DEFAULT;
+ default:
+ break;
+ }
+ return NULL;
+ default:
+ return MT7916_EEPROM_DEFAULT;
+ }
+}
+
static int
mt7915_eeprom_load_default(struct mt7915_dev *dev)
{
- char *default_bin = MT7915_EEPROM_DEFAULT;
u8 *eeprom = dev->mt76.eeprom.data;
const struct firmware *fw = NULL;
int ret;
- if (dev->dbdc_support)
- default_bin = MT7915_EEPROM_DEFAULT_DBDC;
-
- if (!is_mt7915(&dev->mt76))
- default_bin = MT7916_EEPROM_DEFAULT;
-
- ret = request_firmware(&fw, default_bin, dev->mt76.dev);
+ ret = request_firmware(&fw, mt7915_eeprom_name(dev), dev->mt76.dev);
if (ret)
return ret;
@@ -109,14 +130,14 @@ static int mt7915_eeprom_load(struct mt7915_dev *dev)
static void mt7915_eeprom_parse_band_config(struct mt7915_phy *phy)
{
struct mt7915_dev *dev = phy->dev;
- bool ext_phy = phy != &dev->phy;
u8 *eeprom = dev->mt76.eeprom.data;
u32 val;
- val = eeprom[MT_EE_WIFI_CONF + ext_phy];
+ val = eeprom[MT_EE_WIFI_CONF + phy->band_idx];
val = FIELD_GET(MT_EE_WIFI_CONF0_BAND_SEL, val);
- if (val == MT_EE_BAND_SEL_DEFAULT && dev->dbdc_support)
- val = ext_phy ? MT_EE_BAND_SEL_5GHZ : MT_EE_BAND_SEL_2GHZ;
+ if (val == MT_EE_BAND_SEL_DEFAULT &&
+ (!is_mt7915(&dev->mt76) || dev->dbdc_support))
+ val = phy->band_idx ? MT_EE_BAND_SEL_5GHZ : MT_EE_BAND_SEL_2GHZ;
switch (val) {
case MT_EE_BAND_SEL_5GHZ:
@@ -135,7 +156,7 @@ static void mt7915_eeprom_parse_band_config(struct mt7915_phy *phy)
void mt7915_eeprom_parse_hw_cap(struct mt7915_dev *dev,
struct mt7915_phy *phy)
{
- u8 nss, nss_band, *eeprom = dev->mt76.eeprom.data;
+ u8 nss, nss_band, nss_band_max, *eeprom = dev->mt76.eeprom.data;
struct mt76_phy *mphy = phy->mt76;
bool ext_phy = phy != &dev->phy;
@@ -147,7 +168,7 @@ void mt7915_eeprom_parse_hw_cap(struct mt7915_dev *dev,
eeprom[MT_EE_WIFI_CONF]);
} else {
nss = FIELD_GET(MT_EE_WIFI_CONF0_TX_PATH,
- eeprom[MT_EE_WIFI_CONF + ext_phy]);
+ eeprom[MT_EE_WIFI_CONF + phy->band_idx]);
}
if (!nss || nss > 4)
@@ -155,32 +176,42 @@ void mt7915_eeprom_parse_hw_cap(struct mt7915_dev *dev,
/* read tx/rx stream */
nss_band = nss;
+
if (dev->dbdc_support) {
if (is_mt7915(&dev->mt76)) {
nss_band = FIELD_GET(MT_EE_WIFI_CONF3_TX_PATH_B0,
eeprom[MT_EE_WIFI_CONF + 3]);
- if (ext_phy)
+ if (phy->band_idx)
nss_band = FIELD_GET(MT_EE_WIFI_CONF3_TX_PATH_B1,
eeprom[MT_EE_WIFI_CONF + 3]);
} else {
nss_band = FIELD_GET(MT_EE_WIFI_CONF_STREAM_NUM,
- eeprom[MT_EE_WIFI_CONF + 2 + ext_phy]);
+ eeprom[MT_EE_WIFI_CONF + 2 + phy->band_idx]);
}
- if (!nss_band || nss_band > 2)
- nss_band = 2;
+ nss_band_max = is_mt7986(&dev->mt76) ?
+ MT_EE_NSS_MAX_DBDC_MA7986 : MT_EE_NSS_MAX_DBDC_MA7915;
+ } else {
+ nss_band_max = is_mt7986(&dev->mt76) ?
+ MT_EE_NSS_MAX_MA7986 : MT_EE_NSS_MAX_MA7915;
}
+ if (!nss_band || nss_band > nss_band_max)
+ nss_band = nss_band_max;
+
if (nss_band > nss) {
- dev_err(dev->mt76.dev,
- "nss mismatch, nss(%d) nss_band(%d) ext_phy(%d)\n",
- nss, nss_band, ext_phy);
+ dev_warn(dev->mt76.dev,
+ "nss mismatch, nss(%d) nss_band(%d) band(%d) ext_phy(%d)\n",
+ nss, nss_band, phy->band_idx, ext_phy);
nss = nss_band;
}
- mphy->chainmask = ext_phy ? (BIT(nss_band) - 1) << 2 : (BIT(nss_band) - 1);
- mphy->antenna_mask = BIT(hweight8(mphy->chainmask)) - 1;
+ mphy->chainmask = BIT(nss) - 1;
+ if (ext_phy)
+ mphy->chainmask <<= dev->chainshift;
+ mphy->antenna_mask = BIT(nss_band) - 1;
dev->chainmask |= mphy->chainmask;
+ dev->chainshift = hweight8(dev->mphy.chainmask);
}
int mt7915_eeprom_init(struct mt7915_dev *dev)
@@ -226,7 +257,7 @@ int mt7915_eeprom_get_target_power(struct mt7915_dev *dev,
if (chan->band == NL80211_BAND_2GHZ) {
u32 power = is_mt7915(&dev->mt76) ?
- MT_EE_TX0_POWER_2G : MT_EE_TX0_POWER_2G_V2;
+ MT_EE_TX0_POWER_2G : MT_EE_TX0_POWER_2G_V2;
index = power + chain_idx * 3;
target_power = eeprom[index];
@@ -236,7 +267,7 @@ int mt7915_eeprom_get_target_power(struct mt7915_dev *dev,
} else {
int group = mt7915_get_channel_group(chan->hw_value);
u32 power = is_mt7915(&dev->mt76) ?
- MT_EE_TX0_POWER_5G : MT_EE_TX0_POWER_5G_V2;
+ MT_EE_TX0_POWER_5G : MT_EE_TX0_POWER_5G_V2;
index = power + chain_idx * 12;
target_power = eeprom[index + group];
@@ -256,10 +287,10 @@ s8 mt7915_eeprom_get_power_delta(struct mt7915_dev *dev, int band)
u32 rate_2g, rate_5g;
rate_2g = is_mt7915(&dev->mt76) ?
- MT_EE_RATE_DELTA_2G : MT_EE_RATE_DELTA_2G_V2;
+ MT_EE_RATE_DELTA_2G : MT_EE_RATE_DELTA_2G_V2;
rate_5g = is_mt7915(&dev->mt76) ?
- MT_EE_RATE_DELTA_5G : MT_EE_RATE_DELTA_5G_V2;
+ MT_EE_RATE_DELTA_5G : MT_EE_RATE_DELTA_5G_V2;
if (band == NL80211_BAND_2GHZ)
val = eeprom[rate_2g];