blob: c657c5bb50068e55801c930a12088bffe47f1462 [file] [log] [blame]
From 0d8aff6fa4ee351350dda83f8cc7ca2b557322ac Mon Sep 17 00:00:00 2001
From: Shayne Chen <shayne.chen@mediatek.com>
Date: Fri, 14 Apr 2023 16:51:59 +0800
Subject: [PATCH 03/98] wifi: mt76: mt7996: add support for auxiliary path
Add support to correctly configure the setting of variants that have
additional TX or RX path.
Change-Id: I1312c193beab5e16aae7161a7e3bdda100b72f8d
Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
---
mt7996/eeprom.c | 21 +++++++++++++++++----
mt7996/eeprom.h | 3 +++
mt7996/mcu.c | 2 +-
mt7996/mt7996.h | 14 ++++++++++++++
4 files changed, 35 insertions(+), 5 deletions(-)
diff --git a/mt7996/eeprom.c b/mt7996/eeprom.c
index 544b6c6..9db7e53 100644
--- a/mt7996/eeprom.c
+++ b/mt7996/eeprom.c
@@ -148,36 +148,49 @@ static int mt7996_eeprom_parse_band_config(struct mt7996_phy *phy)
int mt7996_eeprom_parse_hw_cap(struct mt7996_dev *dev, struct mt7996_phy *phy)
{
- u8 path, nss, band_idx = phy->mt76->band_idx;
+ u8 path, rx_path, nss, band_idx = phy->mt76->band_idx;
u8 *eeprom = dev->mt76.eeprom.data;
struct mt76_phy *mphy = phy->mt76;
+ int max_path = 5, max_nss = 4;
int ret;
switch (band_idx) {
case MT_BAND1:
path = FIELD_GET(MT_EE_WIFI_CONF2_TX_PATH_BAND1,
eeprom[MT_EE_WIFI_CONF + 2]);
+ rx_path = FIELD_GET(MT_EE_WIFI_CONF3_RX_PATH_BAND1,
+ eeprom[MT_EE_WIFI_CONF + 3]);
nss = FIELD_GET(MT_EE_WIFI_CONF5_STREAM_NUM_BAND1,
eeprom[MT_EE_WIFI_CONF + 5]);
break;
case MT_BAND2:
path = FIELD_GET(MT_EE_WIFI_CONF2_TX_PATH_BAND2,
eeprom[MT_EE_WIFI_CONF + 2]);
+ rx_path = FIELD_GET(MT_EE_WIFI_CONF4_RX_PATH_BAND2,
+ eeprom[MT_EE_WIFI_CONF + 4]);
nss = FIELD_GET(MT_EE_WIFI_CONF5_STREAM_NUM_BAND2,
eeprom[MT_EE_WIFI_CONF + 5]);
break;
default:
path = FIELD_GET(MT_EE_WIFI_CONF1_TX_PATH_BAND0,
eeprom[MT_EE_WIFI_CONF + 1]);
+ rx_path = FIELD_GET(MT_EE_WIFI_CONF3_RX_PATH_BAND0,
+ eeprom[MT_EE_WIFI_CONF + 3]);
nss = FIELD_GET(MT_EE_WIFI_CONF4_STREAM_NUM_BAND0,
eeprom[MT_EE_WIFI_CONF + 4]);
break;
}
- if (!path || path > 4)
- path = 4;
+ if (!path || path > max_path)
+ path = max_path;
- nss = min_t(u8, min_t(u8, 4, nss), path);
+ if (!nss || nss > max_nss)
+ nss = max_nss;
+
+ nss = min_t(u8, nss, path);
+
+ if (path != rx_path)
+ phy->has_aux_rx = true;
mphy->antenna_mask = BIT(nss) - 1;
mphy->chainmask = (BIT(path) - 1) << dev->chainshift[band_idx];
diff --git a/mt7996/eeprom.h b/mt7996/eeprom.h
index 0c74977..412d6e2 100644
--- a/mt7996/eeprom.h
+++ b/mt7996/eeprom.h
@@ -33,6 +33,9 @@ enum mt7996_eeprom_field {
#define MT_EE_WIFI_CONF1_TX_PATH_BAND0 GENMASK(5, 3)
#define MT_EE_WIFI_CONF2_TX_PATH_BAND1 GENMASK(2, 0)
#define MT_EE_WIFI_CONF2_TX_PATH_BAND2 GENMASK(5, 3)
+#define MT_EE_WIFI_CONF3_RX_PATH_BAND0 GENMASK(2, 0)
+#define MT_EE_WIFI_CONF3_RX_PATH_BAND1 GENMASK(5, 3)
+#define MT_EE_WIFI_CONF4_RX_PATH_BAND2 GENMASK(2, 0)
#define MT_EE_WIFI_CONF4_STREAM_NUM_BAND0 GENMASK(5, 3)
#define MT_EE_WIFI_CONF5_STREAM_NUM_BAND1 GENMASK(2, 0)
#define MT_EE_WIFI_CONF5_STREAM_NUM_BAND2 GENMASK(5, 3)
diff --git a/mt7996/mcu.c b/mt7996/mcu.c
index 3ff70c6..328bea9 100644
--- a/mt7996/mcu.c
+++ b/mt7996/mcu.c
@@ -3178,7 +3178,7 @@ int mt7996_mcu_set_chan_info(struct mt7996_phy *phy, u16 tag)
.center_ch = ieee80211_frequency_to_channel(freq1),
.bw = mt76_connac_chan_bw(chandef),
.tx_path_num = hweight16(phy->mt76->chainmask),
- .rx_path = phy->mt76->chainmask >> dev->chainshift[band_idx],
+ .rx_path = mt7996_rx_chainmask(phy) >> dev->chainshift[band_idx],
.band_idx = band_idx,
.channel_band = ch_band[chandef->chan->band],
};
diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
index c541eaa..ef84173 100644
--- a/mt7996/mt7996.h
+++ b/mt7996/mt7996.h
@@ -206,6 +206,8 @@ struct mt7996_phy {
struct mt76_mib_stats mib;
struct mt76_channel_state state_ts;
+
+ bool has_aux_rx;
};
struct mt7996_dev {
@@ -491,6 +493,18 @@ static inline void mt7996_irq_disable(struct mt7996_dev *dev, u32 mask)
void mt7996_memcpy_fromio(struct mt7996_dev *dev, void *buf, u32 offset,
size_t len);
+static inline u16 mt7996_rx_chainmask(struct mt7996_phy *phy)
+{
+ int max_nss = hweight8(phy->mt76->hw->wiphy->available_antennas_tx);
+ int cur_nss = hweight8(phy->mt76->antenna_mask);
+ u16 tx_chainmask = phy->mt76->chainmask;
+
+ if (cur_nss != max_nss)
+ return tx_chainmask;
+
+ return tx_chainmask | (BIT(fls(tx_chainmask)) * phy->has_aux_rx);
+}
+
void mt7996_mac_init(struct mt7996_dev *dev);
u32 mt7996_mac_wtbl_lmac_addr(struct mt7996_dev *dev, u16 wcid, u8 dw);
bool mt7996_mac_wtbl_update(struct mt7996_dev *dev, int idx, u32 mask);
--
2.18.0