Commit 99ad32a4 authored by Bo Jiao's avatar Bo Jiao Committed by Felix Fietkau
Browse files

mt76: mt7915: add support for MT7986



This adds MT7986 SoC integrated multi-band 4x4 WiFi 6/6E.

Co-developed-by: default avatarPeter Chiu <chui-hao.chiu@mediatek.com>
Signed-off-by: default avatarPeter Chiu <chui-hao.chiu@mediatek.com>
Co-developed-by: default avatarRyder Lee <ryder.lee@mediatek.com>
Signed-off-by: default avatarRyder Lee <ryder.lee@mediatek.com>
Signed-off-by: default avatarSujuan Chen <sujuan.chen@mediatek.com>
Signed-off-by: default avatarBo Jiao <Bo.Jiao@mediatek.com>
Signed-off-by: default avatarFelix Fietkau <nbd@nbd.name>
parent 56bd1c86
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -117,6 +117,11 @@ static inline bool is_mt7916(struct mt76_dev *dev)
	return mt76_chip(dev) == 0x7906;
}

static inline bool is_mt7986(struct mt76_dev *dev)
{
	return mt76_chip(dev) == 0x7986;
}

static inline bool is_mt7622(struct mt76_dev *dev)
{
	if (!IS_ENABLED(CONFIG_MT7622_WMAC))
+10 −0
Original line number Diff line number Diff line
@@ -12,3 +12,13 @@ config MT7915E
	  OFDMA, spatial reuse and dual carrier modulation.

	  To compile this driver as a module, choose M here.

config MT7986_WMAC
	bool "MT7986 (SoC) WMAC support"
	depends on MT7915E
	depends on ARCH_MEDIATEK || COMPILE_TEST
	select REGMAP
	help
	  This adds support for the built-in WMAC on MT7986 SoC device
	  which has the same feature set as a MT7915, but enables 6E
	  support.
+1 −0
Original line number Diff line number Diff line
@@ -6,3 +6,4 @@ mt7915e-y := pci.o init.o dma.o eeprom.o main.o mcu.o mac.o \
	     debugfs.o mmio.o

mt7915e-$(CONFIG_NL80211_TESTMODE) += testmode.o
mt7915e-$(CONFIG_MT7986_WMAC) += soc.o
 No newline at end of file
+51 −20
Original line number Diff line number Diff line
@@ -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;

@@ -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;

@@ -155,6 +176,7 @@ 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,
@@ -167,20 +189,29 @@ void mt7915_eeprom_parse_hw_cap(struct mt7915_dev *dev,
					     eeprom[MT_EE_WIFI_CONF + 2 + ext_phy]);
		}

		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,
		dev_warn(dev->mt76.dev,
			 "nss mismatch, nss(%d) nss_band(%d) ext_phy(%d)\n",
			 nss, nss_band, 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)
+13 −0
Original line number Diff line number Diff line
@@ -56,6 +56,19 @@ enum mt7915_eeprom_field {
#define MT_EE_RATE_DELTA_SIGN			BIT(6)
#define MT_EE_RATE_DELTA_EN			BIT(7)

#define MT_EE_NSS_MAX_MA7915			4
#define MT_EE_NSS_MAX_DBDC_MA7915		2
#define MT_EE_NSS_MAX_MA7986			4
#define MT_EE_NSS_MAX_DBDC_MA7986		4

enum mt7915_adie_sku {
	MT7976_ONE_ADIE_DBDC = 0x7,
	MT7975_ONE_ADIE	= 0x8,
	MT7976_ONE_ADIE	= 0xa,
	MT7975_DUAL_ADIE = 0xd,
	MT7976_DUAL_ADIE = 0xf,
};

enum mt7915_eeprom_band {
	MT_EE_BAND_SEL_DEFAULT,
	MT_EE_BAND_SEL_5GHZ,
Loading