Commit b4d093e3 authored by MeiChia Chiu's avatar MeiChia Chiu Committed by Felix Fietkau

mt76: mt7915: add 6 GHz support

Basic 6 GHz support is added to mt76.
Modification includes:
1. Add 6 GHz E2P definition
2. Register 6 GHz HE cap
3. Refactor existing code of adding a STA

This adds support for Wi-Fi 6E on MT7986/MT7916.
Detailed link:
https://www.mediatek.com/products/mediatek-filogic-830
Detailed link:
https://www.mediatek.com/products/products/broadband-wifi/mediatek-filogic-630Reviewed-by: default avatarRyder Lee <ryder.lee@mediatek.com>
Signed-off-by: default avatarShayne Chen <Shayne.Chen@mediatek.com>
Signed-off-by: default avatarPeter Chiu <Chui-Hao.Chiu@mediatek.com>
Signed-off-by: default avatarMoney Wang <Money.Wang@mediatek.com>
Signed-off-by: default avatarMeiChia Chiu <MeiChia.Chiu@mediatek.com>
Signed-off-by: default avatarFelix Fietkau <nbd@nbd.name>
parent 37b5e57b
...@@ -135,9 +135,24 @@ static void mt7915_eeprom_parse_band_config(struct mt7915_phy *phy) ...@@ -135,9 +135,24 @@ static void mt7915_eeprom_parse_band_config(struct mt7915_phy *phy)
val = eeprom[MT_EE_WIFI_CONF + phy->band_idx]; val = eeprom[MT_EE_WIFI_CONF + phy->band_idx];
val = FIELD_GET(MT_EE_WIFI_CONF0_BAND_SEL, val); val = FIELD_GET(MT_EE_WIFI_CONF0_BAND_SEL, val);
if (val == MT_EE_BAND_SEL_DEFAULT &&
(!is_mt7915(&dev->mt76) || dev->dbdc_support)) if (!is_mt7915(&dev->mt76)) {
val = phy->band_idx ? MT_EE_BAND_SEL_5GHZ : MT_EE_BAND_SEL_2GHZ; switch (val) {
case MT_EE_V2_BAND_SEL_5GHZ:
phy->mt76->cap.has_5ghz = true;
return;
case MT_EE_V2_BAND_SEL_6GHZ:
phy->mt76->cap.has_6ghz = true;
return;
case MT_EE_V2_BAND_SEL_5GHZ_6GHZ:
phy->mt76->cap.has_5ghz = true;
phy->mt76->cap.has_6ghz = true;
return;
default:
phy->mt76->cap.has_2ghz = true;
return;
}
}
switch (val) { switch (val) {
case MT_EE_BAND_SEL_5GHZ: case MT_EE_BAND_SEL_5GHZ:
......
...@@ -76,6 +76,13 @@ enum mt7915_eeprom_band { ...@@ -76,6 +76,13 @@ enum mt7915_eeprom_band {
MT_EE_BAND_SEL_DUAL, MT_EE_BAND_SEL_DUAL,
}; };
enum {
MT_EE_V2_BAND_SEL_2GHZ,
MT_EE_V2_BAND_SEL_5GHZ,
MT_EE_V2_BAND_SEL_6GHZ,
MT_EE_V2_BAND_SEL_5GHZ_6GHZ,
};
enum mt7915_sku_rate_group { enum mt7915_sku_rate_group {
SKU_CCK, SKU_CCK,
SKU_OFDM, SKU_OFDM,
......
...@@ -872,7 +872,7 @@ mt7915_init_he_caps(struct mt7915_phy *phy, enum nl80211_band band, ...@@ -872,7 +872,7 @@ mt7915_init_he_caps(struct mt7915_phy *phy, enum nl80211_band band,
if (band == NL80211_BAND_2GHZ) if (band == NL80211_BAND_2GHZ)
he_cap_elem->phy_cap_info[0] = he_cap_elem->phy_cap_info[0] =
IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_IN_2G; IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_IN_2G;
else if (band == NL80211_BAND_5GHZ) else
he_cap_elem->phy_cap_info[0] = he_cap_elem->phy_cap_info[0] =
IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G | IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G |
IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G | IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G |
...@@ -911,7 +911,7 @@ mt7915_init_he_caps(struct mt7915_phy *phy, enum nl80211_band band, ...@@ -911,7 +911,7 @@ mt7915_init_he_caps(struct mt7915_phy *phy, enum nl80211_band band,
if (band == NL80211_BAND_2GHZ) if (band == NL80211_BAND_2GHZ)
he_cap_elem->phy_cap_info[0] |= he_cap_elem->phy_cap_info[0] |=
IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_RU_MAPPING_IN_2G; IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_RU_MAPPING_IN_2G;
else if (band == NL80211_BAND_5GHZ) else
he_cap_elem->phy_cap_info[0] |= he_cap_elem->phy_cap_info[0] |=
IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_RU_MAPPING_IN_5G; IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_RU_MAPPING_IN_5G;
...@@ -961,6 +961,21 @@ mt7915_init_he_caps(struct mt7915_phy *phy, enum nl80211_band band, ...@@ -961,6 +961,21 @@ mt7915_init_he_caps(struct mt7915_phy *phy, enum nl80211_band band,
u8_encode_bits(IEEE80211_HE_PHY_CAP9_NOMINAL_PKT_PADDING_16US, u8_encode_bits(IEEE80211_HE_PHY_CAP9_NOMINAL_PKT_PADDING_16US,
IEEE80211_HE_PHY_CAP9_NOMINAL_PKT_PADDING_MASK); IEEE80211_HE_PHY_CAP9_NOMINAL_PKT_PADDING_MASK);
} }
if (band == NL80211_BAND_6GHZ) {
u16 cap = IEEE80211_HE_6GHZ_CAP_TX_ANTPAT_CONS |
IEEE80211_HE_6GHZ_CAP_RX_ANTPAT_CONS;
cap |= u16_encode_bits(IEEE80211_HT_MPDU_DENSITY_8,
IEEE80211_HE_6GHZ_CAP_MIN_MPDU_START) |
u16_encode_bits(IEEE80211_VHT_MAX_AMPDU_1024K,
IEEE80211_HE_6GHZ_CAP_MAX_AMPDU_LEN_EXP) |
u16_encode_bits(IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454,
IEEE80211_HE_6GHZ_CAP_MAX_MPDU_LEN);
data[idx].he_6ghz_capa.capa = cpu_to_le16(cap);
}
idx++; idx++;
} }
...@@ -990,6 +1005,15 @@ void mt7915_set_stream_he_caps(struct mt7915_phy *phy) ...@@ -990,6 +1005,15 @@ void mt7915_set_stream_he_caps(struct mt7915_phy *phy)
band->iftype_data = data; band->iftype_data = data;
band->n_iftype_data = n; band->n_iftype_data = n;
} }
if (phy->mt76->cap.has_6ghz) {
data = phy->iftype[NL80211_BAND_6GHZ];
n = mt7915_init_he_caps(phy, NL80211_BAND_6GHZ, data);
band = &phy->mt76->sband_6g.sband;
band->iftype_data = data;
band->n_iftype_data = n;
}
} }
static void mt7915_unregister_ext_phy(struct mt7915_dev *dev) static void mt7915_unregister_ext_phy(struct mt7915_dev *dev)
......
...@@ -638,6 +638,8 @@ mt7915_mac_fill_rx(struct mt7915_dev *dev, struct sk_buff *skb) ...@@ -638,6 +638,8 @@ mt7915_mac_fill_rx(struct mt7915_dev *dev, struct sk_buff *skb)
status->band = mphy->chandef.chan->band; status->band = mphy->chandef.chan->band;
if (status->band == NL80211_BAND_5GHZ) if (status->band == NL80211_BAND_5GHZ)
sband = &mphy->sband_5g.sband; sband = &mphy->sband_5g.sband;
else if (status->band == NL80211_BAND_6GHZ)
sband = &mphy->sband_6g.sband;
else else
sband = &mphy->sband_2g.sband; sband = &mphy->sband_2g.sband;
...@@ -1351,7 +1353,7 @@ mt7915_tx_check_aggr(struct ieee80211_sta *sta, __le32 *txwi) ...@@ -1351,7 +1353,7 @@ mt7915_tx_check_aggr(struct ieee80211_sta *sta, __le32 *txwi)
u16 fc, tid; u16 fc, tid;
u32 val; u32 val;
if (!sta || !sta->ht_cap.ht_supported) if (!sta || !(sta->ht_cap.ht_supported || sta->he_cap.has_he))
return; return;
tid = FIELD_GET(MT_TXD1_TID, le32_to_cpu(txwi[1])); tid = FIELD_GET(MT_TXD1_TID, le32_to_cpu(txwi[1]));
...@@ -1559,6 +1561,8 @@ mt7915_mac_add_txs_skb(struct mt7915_dev *dev, struct mt76_wcid *wcid, int pid, ...@@ -1559,6 +1561,8 @@ mt7915_mac_add_txs_skb(struct mt7915_dev *dev, struct mt76_wcid *wcid, int pid,
if (mphy->chandef.chan->band == NL80211_BAND_5GHZ) if (mphy->chandef.chan->band == NL80211_BAND_5GHZ)
sband = &mphy->sband_5g.sband; sband = &mphy->sband_5g.sband;
else if (mphy->chandef.chan->band == NL80211_BAND_6GHZ)
sband = &mphy->sband_6g.sband;
else else
sband = &mphy->sband_2g.sband; sband = &mphy->sband_2g.sband;
...@@ -1804,7 +1808,7 @@ void mt7915_mac_set_timing(struct mt7915_phy *phy) ...@@ -1804,7 +1808,7 @@ void mt7915_mac_set_timing(struct mt7915_phy *phy)
u32 ofdm = FIELD_PREP(MT_TIMEOUT_VAL_PLCP, 60) | u32 ofdm = FIELD_PREP(MT_TIMEOUT_VAL_PLCP, 60) |
FIELD_PREP(MT_TIMEOUT_VAL_CCA, 28); FIELD_PREP(MT_TIMEOUT_VAL_CCA, 28);
int offset; int offset;
bool is_5ghz = phy->mt76->chandef.chan->band == NL80211_BAND_5GHZ; bool a_band = !(phy->mt76->chandef.chan->band == NL80211_BAND_2GHZ);
if (!test_bit(MT76_STATE_RUNNING, &phy->mt76->state)) if (!test_bit(MT76_STATE_RUNNING, &phy->mt76->state))
return; return;
...@@ -1824,7 +1828,7 @@ void mt7915_mac_set_timing(struct mt7915_phy *phy) ...@@ -1824,7 +1828,7 @@ void mt7915_mac_set_timing(struct mt7915_phy *phy)
mt76_wr(dev, MT_TMAC_CDTR(phy->band_idx), cck + reg_offset); mt76_wr(dev, MT_TMAC_CDTR(phy->band_idx), cck + reg_offset);
mt76_wr(dev, MT_TMAC_ODTR(phy->band_idx), ofdm + reg_offset); mt76_wr(dev, MT_TMAC_ODTR(phy->band_idx), ofdm + reg_offset);
mt76_wr(dev, MT_TMAC_ICR0(phy->band_idx), mt76_wr(dev, MT_TMAC_ICR0(phy->band_idx),
FIELD_PREP(MT_IFS_EIFS_OFDM, is_5ghz ? 84 : 78) | FIELD_PREP(MT_IFS_EIFS_OFDM, a_band ? 84 : 78) |
FIELD_PREP(MT_IFS_RIFS, 2) | FIELD_PREP(MT_IFS_RIFS, 2) |
FIELD_PREP(MT_IFS_SIFS, 10) | FIELD_PREP(MT_IFS_SIFS, 10) |
FIELD_PREP(MT_IFS_SLOT, phy->slottime)); FIELD_PREP(MT_IFS_SLOT, phy->slottime));
...@@ -1832,7 +1836,7 @@ void mt7915_mac_set_timing(struct mt7915_phy *phy) ...@@ -1832,7 +1836,7 @@ void mt7915_mac_set_timing(struct mt7915_phy *phy)
mt76_wr(dev, MT_TMAC_ICR1(phy->band_idx), mt76_wr(dev, MT_TMAC_ICR1(phy->band_idx),
FIELD_PREP(MT_IFS_EIFS_CCK, 314)); FIELD_PREP(MT_IFS_EIFS_CCK, 314));
if (phy->slottime < 20 || is_5ghz) if (phy->slottime < 20 || a_band)
val = MT7915_CFEND_RATE_DEFAULT; val = MT7915_CFEND_RATE_DEFAULT;
else else
val = MT7915_CFEND_RATE_11B; val = MT7915_CFEND_RATE_11B;
......
...@@ -987,6 +987,9 @@ mt7915_mcu_sta_ht_tlv(struct sk_buff *skb, struct ieee80211_sta *sta) ...@@ -987,6 +987,9 @@ mt7915_mcu_sta_ht_tlv(struct sk_buff *skb, struct ieee80211_sta *sta)
struct sta_rec_ht *ht; struct sta_rec_ht *ht;
struct tlv *tlv; struct tlv *tlv;
if (!sta->ht_cap.ht_supported)
return;
tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_HT, sizeof(*ht)); tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_HT, sizeof(*ht));
ht = (struct sta_rec_ht *)tlv; ht = (struct sta_rec_ht *)tlv;
...@@ -1267,6 +1270,9 @@ mt7915_mcu_sta_bfer_tlv(struct mt7915_dev *dev, struct sk_buff *skb, ...@@ -1267,6 +1270,9 @@ mt7915_mcu_sta_bfer_tlv(struct mt7915_dev *dev, struct sk_buff *skb,
}; };
bool ebf; bool ebf;
if (!(sta->ht_cap.ht_supported || sta->he_cap.has_he))
return;
ebf = mt7915_is_ebf_supported(phy, vif, sta, false); ebf = mt7915_is_ebf_supported(phy, vif, sta, false);
if (!ebf && !dev->ibf) if (!ebf && !dev->ibf)
return; return;
...@@ -1327,6 +1333,9 @@ mt7915_mcu_sta_bfee_tlv(struct mt7915_dev *dev, struct sk_buff *skb, ...@@ -1327,6 +1333,9 @@ mt7915_mcu_sta_bfee_tlv(struct mt7915_dev *dev, struct sk_buff *skb,
struct tlv *tlv; struct tlv *tlv;
u8 nrow = 0; u8 nrow = 0;
if (!(sta->vht_cap.vht_supported || sta->he_cap.has_he))
return;
if (!mt7915_is_ebf_supported(phy, vif, sta, true)) if (!mt7915_is_ebf_supported(phy, vif, sta, true))
return; return;
...@@ -1621,6 +1630,10 @@ mt7915_mcu_sta_rate_ctrl_tlv(struct sk_buff *skb, struct mt7915_dev *dev, ...@@ -1621,6 +1630,10 @@ mt7915_mcu_sta_rate_ctrl_tlv(struct sk_buff *skb, struct mt7915_dev *dev,
if (sta->he_cap.has_he) { if (sta->he_cap.has_he) {
ra->supp_mode |= MODE_HE; ra->supp_mode |= MODE_HE;
cap |= STA_CAP_HE; cap |= STA_CAP_HE;
if (sta->he_6ghz_capa.capa)
ra->af = le16_get_bits(sta->he_6ghz_capa.capa,
IEEE80211_HE_6GHZ_CAP_MAX_AMPDU_LEN_EXP);
} }
ra->sta_cap = cpu_to_le32(cap); ra->sta_cap = cpu_to_le32(cap);
...@@ -1643,7 +1656,7 @@ int mt7915_mcu_add_rate_ctrl(struct mt7915_dev *dev, struct ieee80211_vif *vif, ...@@ -1643,7 +1656,7 @@ int mt7915_mcu_add_rate_ctrl(struct mt7915_dev *dev, struct ieee80211_vif *vif,
* once dev->rc_work changes the settings driver should also * once dev->rc_work changes the settings driver should also
* update sta_rec_he here. * update sta_rec_he here.
*/ */
if (sta->he_cap.has_he && changed) if (changed)
mt7915_mcu_sta_he_tlv(skb, sta, vif); mt7915_mcu_sta_he_tlv(skb, sta, vif);
/* sta_rec_ra accommodates BW, NSS and only MCS range format /* sta_rec_ra accommodates BW, NSS and only MCS range format
...@@ -1712,7 +1725,7 @@ int mt7915_mcu_add_sta(struct mt7915_dev *dev, struct ieee80211_vif *vif, ...@@ -1712,7 +1725,7 @@ int mt7915_mcu_add_sta(struct mt7915_dev *dev, struct ieee80211_vif *vif,
goto out; goto out;
/* tag order is in accordance with firmware dependency. */ /* tag order is in accordance with firmware dependency. */
if (sta && sta->ht_cap.ht_supported) { if (sta) {
/* starec bfer */ /* starec bfer */
mt7915_mcu_sta_bfer_tlv(dev, skb, vif, sta); mt7915_mcu_sta_bfer_tlv(dev, skb, vif, sta);
/* starec ht */ /* starec ht */
...@@ -1729,7 +1742,7 @@ int mt7915_mcu_add_sta(struct mt7915_dev *dev, struct ieee80211_vif *vif, ...@@ -1729,7 +1742,7 @@ int mt7915_mcu_add_sta(struct mt7915_dev *dev, struct ieee80211_vif *vif,
return ret; return ret;
} }
if (sta && sta->ht_cap.ht_supported) { if (sta) {
/* starec amsdu */ /* starec amsdu */
mt7915_mcu_sta_amsdu_tlv(dev, skb, vif, sta); mt7915_mcu_sta_amsdu_tlv(dev, skb, vif, sta);
/* starec he */ /* starec he */
...@@ -2772,6 +2785,11 @@ int mt7915_mcu_rdd_background_enable(struct mt7915_phy *phy, ...@@ -2772,6 +2785,11 @@ int mt7915_mcu_rdd_background_enable(struct mt7915_phy *phy,
int mt7915_mcu_set_chan_info(struct mt7915_phy *phy, int cmd) int mt7915_mcu_set_chan_info(struct mt7915_phy *phy, int cmd)
{ {
static const u8 ch_band[] = {
[NL80211_BAND_2GHZ] = 0,
[NL80211_BAND_5GHZ] = 1,
[NL80211_BAND_6GHZ] = 2,
};
struct mt7915_dev *dev = phy->dev; struct mt7915_dev *dev = phy->dev;
struct cfg80211_chan_def *chandef = &phy->mt76->chandef; struct cfg80211_chan_def *chandef = &phy->mt76->chandef;
int freq1 = chandef->center_freq1; int freq1 = chandef->center_freq1;
...@@ -2799,7 +2817,7 @@ int mt7915_mcu_set_chan_info(struct mt7915_phy *phy, int cmd) ...@@ -2799,7 +2817,7 @@ int mt7915_mcu_set_chan_info(struct mt7915_phy *phy, int cmd)
.tx_streams_num = hweight8(phy->mt76->antenna_mask), .tx_streams_num = hweight8(phy->mt76->antenna_mask),
.rx_streams = phy->mt76->antenna_mask, .rx_streams = phy->mt76->antenna_mask,
.band_idx = phy->band_idx, .band_idx = phy->band_idx,
.channel_band = chandef->chan->band, .channel_band = ch_band[chandef->chan->band],
}; };
#ifdef CONFIG_NL80211_TESTMODE #ifdef CONFIG_NL80211_TESTMODE
...@@ -3461,6 +3479,8 @@ int mt7915_mcu_get_rx_rate(struct mt7915_phy *phy, struct ieee80211_vif *vif, ...@@ -3461,6 +3479,8 @@ int mt7915_mcu_get_rx_rate(struct mt7915_phy *phy, struct ieee80211_vif *vif,
case MT_PHY_TYPE_OFDM: case MT_PHY_TYPE_OFDM:
if (mphy->chandef.chan->band == NL80211_BAND_5GHZ) if (mphy->chandef.chan->band == NL80211_BAND_5GHZ)
sband = &mphy->sband_5g.sband; sband = &mphy->sband_5g.sband;
else if (mphy->chandef.chan->band == NL80211_BAND_6GHZ)
sband = &mphy->sband_6g.sband;
else else
sband = &mphy->sband_2g.sband; sband = &mphy->sband_2g.sband;
......
...@@ -227,7 +227,7 @@ struct mt7915_phy { ...@@ -227,7 +227,7 @@ struct mt7915_phy {
struct mt76_phy *mt76; struct mt76_phy *mt76;
struct mt7915_dev *dev; struct mt7915_dev *dev;
struct ieee80211_sband_iftype_data iftype[2][NUM_NL80211_IFTYPES]; struct ieee80211_sband_iftype_data iftype[NUM_NL80211_BANDS][NUM_NL80211_IFTYPES];
struct ieee80211_vif *monitor_vif; struct ieee80211_vif *monitor_vif;
......
...@@ -271,6 +271,8 @@ mt7915_tm_set_tx_len(struct mt7915_phy *phy, u32 tx_time) ...@@ -271,6 +271,8 @@ mt7915_tm_set_tx_len(struct mt7915_phy *phy, u32 tx_time)
case MT76_TM_TX_MODE_OFDM: case MT76_TM_TX_MODE_OFDM:
if (mphy->chandef.chan->band == NL80211_BAND_5GHZ) if (mphy->chandef.chan->band == NL80211_BAND_5GHZ)
sband = &mphy->sband_5g.sband; sband = &mphy->sband_5g.sband;
else if (mphy->chandef.chan->band == NL80211_BAND_6GHZ)
sband = &mphy->sband_6g.sband;
else else
sband = &mphy->sband_2g.sband; sband = &mphy->sband_2g.sband;
...@@ -572,6 +574,8 @@ mt7915_tm_set_tx_cont(struct mt7915_phy *phy, bool en) ...@@ -572,6 +574,8 @@ mt7915_tm_set_tx_cont(struct mt7915_phy *phy, bool en)
if (chandef->chan->band == NL80211_BAND_5GHZ) if (chandef->chan->band == NL80211_BAND_5GHZ)
sband = &phy->mt76->sband_5g.sband; sband = &phy->mt76->sband_5g.sband;
else if (chandef->chan->band == NL80211_BAND_6GHZ)
sband = &phy->mt76->sband_6g.sband;
else else
sband = &phy->mt76->sband_2g.sband; sband = &phy->mt76->sband_2g.sband;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment