2021-08-24 10:23:42

by Lorenzo Bianconi

[permalink] [raw]
Subject: [PATCH 0/9] introduce 6GHz support to mt7921 driver

Lorenzo Bianconi (9):
mt76: connac: set 6G phymode in mt76_connac_get_phy_mode{,v2}
mt76: connac: enable 6GHz band for hw scan
mt76: connac: add 6GHz support to mt76_connac_mcu_set_channel_domain
mt76: connac: set 6G phymode in single-sku support
mt76: connac: add 6GHz support to mt76_connac_mcu_sta_tlv
mt76: connac: add 6GHz support to mt76_connac_mcu_uni_add_bss
mt76: connac: enable hw amsdu @ 6GHz
mt76: add 6GHz support
mt76: mt7921: add 6GHz support

drivers/net/wireless/mediatek/mt76/eeprom.c | 3 +
drivers/net/wireless/mediatek/mt76/mac80211.c | 128 +++++++++++++++-
drivers/net/wireless/mediatek/mt76/mt76.h | 1 +
.../wireless/mediatek/mt76/mt76_connac_mcu.c | 139 +++++++++++++++---
.../wireless/mediatek/mt76/mt76_connac_mcu.h | 19 ++-
.../net/wireless/mediatek/mt76/mt7921/mac.c | 33 +++--
.../net/wireless/mediatek/mt76/mt7921/main.c | 39 ++++-
.../net/wireless/mediatek/mt76/mt7921/mcu.c | 6 +-
.../wireless/mediatek/mt76/mt7921/mt7921.h | 2 +-
9 files changed, 324 insertions(+), 46 deletions(-)

--
2.31.1


2021-08-24 10:24:13

by Lorenzo Bianconi

[permalink] [raw]
Subject: [PATCH 5/9] mt76: connac: add 6GHz support to mt76_connac_mcu_sta_tlv

Introduce sta_rec_he_6g_capa tlv in order configure the mcu with 6GHz
capabilities. This is a preliminary patch to enable 6GHz band for
mt7921 devices.

Tested-by: Deren Wu <[email protected]>
Signed-off-by: Lorenzo Bianconi <[email protected]>
---
drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c | 12 +++++++++++-
drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h | 9 +++++++++
2 files changed, 20 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c
index 8e1475aa35ac..ab44e61e3aaf 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c
@@ -770,8 +770,18 @@ void mt76_connac_mcu_sta_tlv(struct mt76_phy *mphy, struct sk_buff *skb,
mt76_connac_mcu_sta_amsdu_tlv(skb, sta, vif);

/* starec he */
- if (sta->he_cap.has_he)
+ if (sta->he_cap.has_he) {
mt76_connac_mcu_sta_he_tlv(skb, sta);
+ if (band == NL80211_BAND_6GHZ &&
+ sta_state == MT76_STA_INFO_STATE_ASSOC) {
+ struct sta_rec_he_6g_capa *he_6g_capa;
+
+ tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_HE_6G,
+ sizeof(*he_6g_capa));
+ he_6g_capa = (struct sta_rec_he_6g_capa *)tlv;
+ he_6g_capa->capa = sta->he_6ghz_capa.capa;
+ }
+ }

tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_PHY, sizeof(*phy));
phy = (struct sta_rec_phy *)tlv;
diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h
index 0f11574af535..5ab5e185a8bb 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h
@@ -145,6 +145,13 @@ struct sta_rec_phy {
u8 rsv[2];
} __packed;

+struct sta_rec_he_6g_capa {
+ __le16 tag;
+ __le16 len;
+ __le16 capa;
+ u8 rsv[2];
+} __packed;
+
/* wtbl_rec */

struct wtbl_req_hdr {
@@ -303,6 +310,7 @@ struct wtbl_raw {
sizeof(struct sta_rec_vht) + \
sizeof(struct sta_rec_uapsd) + \
sizeof(struct sta_rec_amsdu) + \
+ sizeof(struct sta_rec_he_6g_capa) + \
sizeof(struct tlv) + \
MT76_CONNAC_WTBL_UPDATE_MAX_SIZE)

@@ -329,6 +337,7 @@ enum {
STA_REC_MUEDCA,
STA_REC_BFEE,
STA_REC_PHY = 0x15,
+ STA_REC_HE_6G = 0x17,
STA_REC_MAX_NUM
};

--
2.31.1

2021-08-24 10:24:25

by Lorenzo Bianconi

[permalink] [raw]
Subject: [PATCH 1/9] mt76: connac: set 6G phymode in mt76_connac_get_phy_mode{,v2}

This is a preliminary patch to support 6GHz band on mt7921 devices.

Tested-by: Deren Wu <[email protected]>
Signed-off-by: Lorenzo Bianconi <[email protected]>
---
drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c
index 9c0f86eefd75..8b72ed77881c 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c
@@ -691,7 +691,7 @@ mt76_connac_get_phy_mode_v2(struct mt76_phy *mphy, struct ieee80211_vif *vif,

if (he_cap->has_he)
mode |= PHY_TYPE_BIT_HE;
- } else if (band == NL80211_BAND_5GHZ) {
+ } else if (band == NL80211_BAND_5GHZ || band == NL80211_BAND_6GHZ) {
mode |= PHY_TYPE_BIT_OFDM;

if (ht_cap->ht_supported)
@@ -1154,7 +1154,7 @@ mt76_connac_get_phy_mode(struct mt76_phy *phy, struct ieee80211_vif *vif,

if (he_cap->has_he)
mode |= PHY_MODE_AX_24G;
- } else if (band == NL80211_BAND_5GHZ) {
+ } else if (band == NL80211_BAND_5GHZ || band == NL80211_BAND_6GHZ) {
mode |= PHY_MODE_A;

if (ht_cap->ht_supported)
@@ -1163,8 +1163,12 @@ mt76_connac_get_phy_mode(struct mt76_phy *phy, struct ieee80211_vif *vif,
if (vht_cap->vht_supported)
mode |= PHY_MODE_AC;

- if (he_cap->has_he)
- mode |= PHY_MODE_AX_5G;
+ if (he_cap->has_he) {
+ if (band == NL80211_BAND_6GHZ)
+ mode |= PHY_MODE_AX_6G;
+ else
+ mode |= PHY_MODE_AX_5G;
+ }
}

return mode;
--
2.31.1

2021-08-24 10:26:03

by Lorenzo Bianconi

[permalink] [raw]
Subject: [PATCH 3/9] mt76: connac: add 6GHz support to mt76_connac_mcu_set_channel_domain

Configure 6GHz channels defining mcu channel domain. This is a
preliminary patch to enable 6GHz band on mt7921 devices.

Tested-by: Deren Wu <[email protected]>
Signed-off-by: Lorenzo Bianconi <[email protected]>
---
drivers/net/wireless/mediatek/mt76/mt76.h | 1 +
.../wireless/mediatek/mt76/mt76_connac_mcu.c | 29 +++++++++++++++----
2 files changed, 24 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
index 8e7fedfd1758..a394ea8a1856 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -624,6 +624,7 @@ struct mt76_phy {
struct mt76_hw_cap cap;
struct mt76_sband sband_2g;
struct mt76_sband sband_5g;
+ struct mt76_sband sband_6g;

u8 macaddr[ETH_ALEN];

diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c
index 8858a06ebd95..f5c1a7d9306e 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c
@@ -74,7 +74,7 @@ EXPORT_SYMBOL_GPL(mt76_connac_mcu_init_download);

int mt76_connac_mcu_set_channel_domain(struct mt76_phy *phy)
{
- struct mt76_dev *dev = phy->dev;
+ int len, i, n_max_channels, n_2ch = 0, n_5ch = 0, n_6ch = 0;
struct mt76_connac_mcu_channel_domain {
u8 alpha2[4]; /* regulatory_request.alpha2 */
u8 bw_2g; /* BW_20_40M 0
@@ -84,25 +84,29 @@ int mt76_connac_mcu_set_channel_domain(struct mt76_phy *phy)
* BW_20_40_80_8080M 4
*/
u8 bw_5g;
- __le16 pad;
+ u8 bw_6g;
+ u8 pad;
u8 n_2ch;
u8 n_5ch;
- __le16 pad2;
+ u8 n_6ch;
+ u8 pad2;
} __packed hdr = {
.bw_2g = 0,
- .bw_5g = 3,
+ .bw_5g = 3, /* BW_20_40_80_160M */
+ .bw_6g = 3,
};
struct mt76_connac_mcu_chan {
__le16 hw_value;
__le16 pad;
__le32 flags;
} __packed channel;
- int len, i, n_max_channels, n_2ch = 0, n_5ch = 0;
+ struct mt76_dev *dev = phy->dev;
struct ieee80211_channel *chan;
struct sk_buff *skb;

n_max_channels = phy->sband_2g.sband.n_channels +
- phy->sband_5g.sband.n_channels;
+ phy->sband_5g.sband.n_channels +
+ phy->sband_6g.sband.n_channels;
len = sizeof(hdr) + n_max_channels * sizeof(channel);

skb = mt76_mcu_msg_alloc(dev, NULL, len);
@@ -135,11 +139,24 @@ int mt76_connac_mcu_set_channel_domain(struct mt76_phy *phy)
skb_put_data(skb, &channel, sizeof(channel));
n_5ch++;
}
+ for (i = 0; i < phy->sband_6g.sband.n_channels; i++) {
+ chan = &phy->sband_6g.sband.channels[i];
+ if (chan->flags & IEEE80211_CHAN_DISABLED)
+ continue;
+
+ channel.hw_value = cpu_to_le16(chan->hw_value);
+ channel.flags = cpu_to_le32(chan->flags);
+ channel.pad = 0;
+
+ skb_put_data(skb, &channel, sizeof(channel));
+ n_6ch++;
+ }

BUILD_BUG_ON(sizeof(dev->alpha2) > sizeof(hdr.alpha2));
memcpy(hdr.alpha2, dev->alpha2, sizeof(dev->alpha2));
hdr.n_2ch = n_2ch;
hdr.n_5ch = n_5ch;
+ hdr.n_6ch = n_6ch;

memcpy(__skb_push(skb, sizeof(hdr)), &hdr, sizeof(hdr));

--
2.31.1

2021-08-24 10:26:03

by Lorenzo Bianconi

[permalink] [raw]
Subject: [PATCH 8/9] mt76: add 6GHz support

Introduce 6GHz channel list in mt76 module. This is a preliminary patch
to unlock 6GHz band for mt7921 devices.

Tested-by: Deren Wu <[email protected]>
Signed-off-by: Lorenzo Bianconi <[email protected]>
---
drivers/net/wireless/mediatek/mt76/mac80211.c | 128 ++++++++++++++++--
1 file changed, 120 insertions(+), 8 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mac80211.c b/drivers/net/wireless/mediatek/mt76/mac80211.c
index e282c627e25c..c1b2af458691 100644
--- a/drivers/net/wireless/mediatek/mt76/mac80211.c
+++ b/drivers/net/wireless/mediatek/mt76/mac80211.c
@@ -20,6 +20,13 @@
.max_power = 30, \
}

+#define CHAN6G(_idx, _freq) { \
+ .band = NL80211_BAND_6GHZ, \
+ .center_freq = (_freq), \
+ .hw_value = (_idx), \
+ .max_power = 30, \
+}
+
static const struct ieee80211_channel mt76_channels_2ghz[] = {
CHAN2G(1, 2412),
CHAN2G(2, 2417),
@@ -70,6 +77,72 @@ static const struct ieee80211_channel mt76_channels_5ghz[] = {
CHAN5G(173, 5865),
};

+static const struct ieee80211_channel mt76_channels_6ghz[] = {
+ /* UNII-5 */
+ CHAN6G(1, 5955),
+ CHAN6G(5, 5975),
+ CHAN6G(9, 5995),
+ CHAN6G(13, 6015),
+ CHAN6G(17, 6035),
+ CHAN6G(21, 6055),
+ CHAN6G(25, 6075),
+ CHAN6G(29, 6095),
+ CHAN6G(33, 6115),
+ CHAN6G(37, 6135),
+ CHAN6G(41, 6155),
+ CHAN6G(45, 6175),
+ CHAN6G(49, 6195),
+ CHAN6G(53, 6215),
+ CHAN6G(57, 6235),
+ CHAN6G(61, 6255),
+ CHAN6G(65, 6275),
+ CHAN6G(69, 6295),
+ CHAN6G(73, 6315),
+ CHAN6G(77, 6335),
+ CHAN6G(81, 6355),
+ CHAN6G(85, 6375),
+ CHAN6G(89, 6395),
+ CHAN6G(93, 6415),
+ /* UNII-6 */
+ CHAN6G(97, 6435),
+ CHAN6G(101, 6455),
+ CHAN6G(105, 6475),
+ CHAN6G(109, 6495),
+ CHAN6G(113, 6515),
+ CHAN6G(117, 6535),
+ /* UNII-7 */
+ CHAN6G(121, 6555),
+ CHAN6G(125, 6575),
+ CHAN6G(129, 6595),
+ CHAN6G(133, 6615),
+ CHAN6G(137, 6635),
+ CHAN6G(141, 6655),
+ CHAN6G(145, 6675),
+ CHAN6G(149, 6695),
+ CHAN6G(153, 6715),
+ CHAN6G(157, 6735),
+ CHAN6G(161, 6755),
+ CHAN6G(165, 6775),
+ CHAN6G(169, 6795),
+ CHAN6G(173, 6815),
+ CHAN6G(177, 6835),
+ CHAN6G(181, 6855),
+ CHAN6G(185, 6875),
+ /* UNII-8 */
+ CHAN6G(189, 6895),
+ CHAN6G(193, 6915),
+ CHAN6G(197, 6935),
+ CHAN6G(201, 6955),
+ CHAN6G(205, 6975),
+ CHAN6G(209, 6995),
+ CHAN6G(213, 7015),
+ CHAN6G(217, 7035),
+ CHAN6G(221, 7055),
+ CHAN6G(225, 7075),
+ CHAN6G(229, 7095),
+ CHAN6G(233, 7115),
+};
+
static const struct ieee80211_tpt_blink mt76_tpt_blink[] = {
{ .throughput = 0 * 1024, .blink_time = 334 },
{ .throughput = 1 * 1024, .blink_time = 260 },
@@ -194,13 +267,16 @@ void mt76_set_stream_caps(struct mt76_phy *phy, bool vht)
mt76_init_stream_cap(phy, &phy->sband_2g.sband, false);
if (phy->cap.has_5ghz)
mt76_init_stream_cap(phy, &phy->sband_5g.sband, vht);
+ if (phy->cap.has_6ghz)
+ mt76_init_stream_cap(phy, &phy->sband_6g.sband, vht);
}
EXPORT_SYMBOL_GPL(mt76_set_stream_caps);

static int
mt76_init_sband(struct mt76_phy *phy, struct mt76_sband *msband,
const struct ieee80211_channel *chan, int n_chan,
- struct ieee80211_rate *rates, int n_rates, bool vht)
+ struct ieee80211_rate *rates, int n_rates,
+ bool ht, bool vht)
{
struct ieee80211_supported_band *sband = &msband->sband;
struct ieee80211_sta_vht_cap *vht_cap;
@@ -224,6 +300,9 @@ mt76_init_sband(struct mt76_phy *phy, struct mt76_sband *msband,
sband->bitrates = rates;
sband->n_bitrates = n_rates;

+ if (!ht)
+ return 0;
+
ht_cap = &sband->ht_cap;
ht_cap->ht_supported = true;
ht_cap->cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
@@ -260,7 +339,7 @@ mt76_init_sband_2g(struct mt76_phy *phy, struct ieee80211_rate *rates,

return mt76_init_sband(phy, &phy->sband_2g, mt76_channels_2ghz,
ARRAY_SIZE(mt76_channels_2ghz), rates,
- n_rates, false);
+ n_rates, true, false);
}

static int
@@ -271,7 +350,18 @@ mt76_init_sband_5g(struct mt76_phy *phy, struct ieee80211_rate *rates,

return mt76_init_sband(phy, &phy->sband_5g, mt76_channels_5ghz,
ARRAY_SIZE(mt76_channels_5ghz), rates,
- n_rates, vht);
+ n_rates, true, vht);
+}
+
+static int
+mt76_init_sband_6g(struct mt76_phy *phy, struct ieee80211_rate *rates,
+ int n_rates)
+{
+ phy->hw->wiphy->bands[NL80211_BAND_6GHZ] = &phy->sband_6g.sband;
+
+ return mt76_init_sband(phy, &phy->sband_6g, mt76_channels_6ghz,
+ ARRAY_SIZE(mt76_channels_6ghz), rates,
+ n_rates, false, false);
}

static void
@@ -400,9 +490,16 @@ int mt76_register_phy(struct mt76_phy *phy, bool vht,
return ret;
}

+ if (phy->cap.has_6ghz) {
+ ret = mt76_init_sband_6g(phy, rates + 4, n_rates - 4);
+ if (ret)
+ return ret;
+ }
+
wiphy_read_of_freq_limits(phy->hw->wiphy);
mt76_check_sband(phy, &phy->sband_2g, NL80211_BAND_2GHZ);
mt76_check_sband(phy, &phy->sband_5g, NL80211_BAND_5GHZ);
+ mt76_check_sband(phy, &phy->sband_6g, NL80211_BAND_6GHZ);

ret = ieee80211_register_hw(phy->hw);
if (ret)
@@ -510,9 +607,16 @@ int mt76_register_device(struct mt76_dev *dev, bool vht,
return ret;
}

+ if (phy->cap.has_6ghz) {
+ ret = mt76_init_sband_6g(phy, rates + 4, n_rates - 4);
+ if (ret)
+ return ret;
+ }
+
wiphy_read_of_freq_limits(hw->wiphy);
mt76_check_sband(&dev->phy, &phy->sband_2g, NL80211_BAND_2GHZ);
mt76_check_sband(&dev->phy, &phy->sband_5g, NL80211_BAND_5GHZ);
+ mt76_check_sband(&dev->phy, &phy->sband_6g, NL80211_BAND_6GHZ);

if (IS_ENABLED(CONFIG_MT76_LEDS)) {
ret = mt76_led_init(dev);
@@ -657,6 +761,8 @@ mt76_channel_state(struct mt76_phy *phy, struct ieee80211_channel *c)

if (c->band == NL80211_BAND_2GHZ)
msband = &phy->sband_2g;
+ else if (c->band == NL80211_BAND_6GHZ)
+ msband = &phy->sband_6g;
else
msband = &phy->sband_5g;

@@ -732,10 +838,16 @@ int mt76_get_survey(struct ieee80211_hw *hw, int idx,
if (idx == 0 && dev->drv->update_survey)
mt76_update_survey(phy);

- sband = &phy->sband_2g;
- if (idx >= sband->sband.n_channels) {
- idx -= sband->sband.n_channels;
+ if (idx >= phy->sband_2g.sband.n_channels +
+ phy->sband_5g.sband.n_channels) {
+ idx -= (phy->sband_2g.sband.n_channels +
+ phy->sband_5g.sband.n_channels);
+ sband = &phy->sband_6g;
+ } else if (idx >= phy->sband_2g.sband.n_channels) {
+ idx -= phy->sband_2g.sband.n_channels;
sband = &phy->sband_5g;
+ } else {
+ sband = &phy->sband_2g;
}

if (idx >= sband->sband.n_channels) {
@@ -1285,7 +1397,7 @@ int mt76_get_rate(struct mt76_dev *dev,
int i, offset = 0, len = sband->n_bitrates;

if (cck) {
- if (sband == &dev->phy.sband_5g.sband)
+ if (sband != &dev->phy.sband_2g.sband)
return 0;

idx &= ~BIT(2); /* short preamble */
@@ -1357,7 +1469,7 @@ u16 mt76_calculate_default_rate(struct mt76_phy *phy, int rateidx)
int offset = 0;
struct ieee80211_rate *rate;

- if (phy->chandef.chan->band == NL80211_BAND_5GHZ)
+ if (phy->chandef.chan->band != NL80211_BAND_2GHZ)
offset = 4;

rate = &mt76_rates[offset + rateidx];
--
2.31.1

2021-08-24 10:26:16

by Lorenzo Bianconi

[permalink] [raw]
Subject: [PATCH 7/9] mt76: connac: enable hw amsdu @ 6GHz

This is a preliminary patch to enable 6GHz band for mt7921 devices.

Tested-by: Deren Wu <[email protected]>
Signed-off-by: Lorenzo Bianconi <[email protected]>
---
drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c
index 3b9c4180f954..10198c0c065b 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c
@@ -766,7 +766,7 @@ void mt76_connac_mcu_sta_tlv(struct mt76_phy *mphy, struct sk_buff *skb,
if (!is_mt7921(dev))
return;

- if (sta->ht_cap.ht_supported)
+ if (sta->ht_cap.ht_supported || sta->he_cap.has_he)
mt76_connac_mcu_sta_amsdu_tlv(skb, sta, vif);

/* starec he */
--
2.31.1

2021-08-24 10:26:16

by Lorenzo Bianconi

[permalink] [raw]
Subject: [PATCH 6/9] mt76: connac: add 6GHz support to mt76_connac_mcu_uni_add_bss

This is a preliminary patch to enable 6GHz band for mt7921 devices.

Tested-by: Deren Wu <[email protected]>
Signed-off-by: Lorenzo Bianconi <[email protected]>
---
drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c | 11 +++++++++--
drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h | 8 ++++++--
2 files changed, 15 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c
index ab44e61e3aaf..3b9c4180f954 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c
@@ -1292,7 +1292,8 @@ int mt76_connac_mcu_uni_add_bss(struct mt76_phy *phy,
u8 short_st;
u8 ht_op_info;
u8 sco;
- u8 pad[3];
+ u8 band;
+ u8 pad[2];
} __packed rlm;
} __packed rlm_req = {
.hdr = {
@@ -1308,13 +1309,19 @@ int mt76_connac_mcu_uni_add_bss(struct mt76_phy *phy,
.ht_op_info = 4, /* set HT 40M allowed */
.rx_streams = phy->chainmask,
.short_st = true,
+ .band = band,
},
};
int err, conn_type;
- u8 idx;
+ u8 idx, basic_phy;

idx = mvif->omac_idx > EXT_BSSID_START ? HW_BSSID_0 : mvif->omac_idx;
basic_req.basic.hw_bss_idx = idx;
+ if (band == NL80211_BAND_6GHZ)
+ basic_req.basic.phymode_ext = BIT(0);
+
+ basic_phy = mt76_connac_get_phy_mode_v2(phy, vif, band, NULL);
+ basic_req.basic.nonht_basic_phy = cpu_to_le16(basic_phy);

switch (vif->type) {
case NL80211_IFTYPE_MESH_POINT:
diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h
index 5ab5e185a8bb..ea46dde364e1 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h
@@ -668,10 +668,14 @@ struct mt76_connac_bss_basic_tlv {
* bit(3): GN
* bit(4): AN
* bit(5): AC
+ * bit(6): AX2
+ * bit(7): AX5
+ * bit(8): AX6
*/
__le16 sta_idx;
- u8 nonht_basic_phy;
- u8 pad[3];
+ __le16 nonht_basic_phy;
+ u8 phymode_ext; /* bit(0) AX_6G */
+ u8 pad[1];
} __packed;

struct mt76_connac_bss_qos_tlv {
--
2.31.1

2021-08-24 10:26:16

by Lorenzo Bianconi

[permalink] [raw]
Subject: [PATCH 4/9] mt76: connac: set 6G phymode in single-sku support

Configure tx rate power for 6GHz channels. This is a preliminary patch
to enable 6GHz band for mt7921 devices.

Tested-by: Deren Wu <[email protected]>
Signed-off-by: Lorenzo Bianconi <[email protected]>
---
drivers/net/wireless/mediatek/mt76/eeprom.c | 3 ++
.../wireless/mediatek/mt76/mt76_connac_mcu.c | 48 +++++++++++++++++--
.../wireless/mediatek/mt76/mt76_connac_mcu.h | 2 +-
3 files changed, 49 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/eeprom.c b/drivers/net/wireless/mediatek/mt76/eeprom.c
index 3b47e85e95e7..376c3bd883e5 100644
--- a/drivers/net/wireless/mediatek/mt76/eeprom.c
+++ b/drivers/net/wireless/mediatek/mt76/eeprom.c
@@ -285,6 +285,9 @@ s8 mt76_get_rate_power_limits(struct mt76_phy *phy,
case NL80211_BAND_5GHZ:
band = '5';
break;
+ case NL80211_BAND_6GHZ:
+ band = '6';
+ break;
default:
return target_power;
}
diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c
index f5c1a7d9306e..8e1475aa35ac 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c
@@ -1839,6 +1839,9 @@ static s8 mt76_connac_get_ch_power(struct mt76_phy *phy,
case NL80211_BAND_5GHZ:
sband = &phy->sband_5g.sband;
break;
+ case NL80211_BAND_6GHZ:
+ sband = &phy->sband_6g.sband;
+ break;
default:
return target_power;
}
@@ -1880,6 +1883,24 @@ mt76_connac_mcu_rate_txpower_band(struct mt76_phy *phy,
142, 144, 149, 151, 153, 155, 157,
159, 161, 165
};
+ static const u8 chan_list_6ghz[] = {
+ 1, 3, 5, 7, 9, 11, 13,
+ 15, 17, 19, 21, 23, 25, 27,
+ 29, 33, 35, 37, 39, 41, 43,
+ 45, 47, 49, 51, 53, 55, 57,
+ 59, 61, 65, 67, 69, 71, 73,
+ 75, 77, 79, 81, 83, 85, 87,
+ 89, 91, 93, 97, 99, 101, 103,
+ 105, 107, 109, 111, 113, 115, 117,
+ 119, 121, 123, 125, 129, 131, 133,
+ 135, 137, 139, 141, 143, 145, 147,
+ 149, 151, 153, 155, 157, 161, 163,
+ 165, 167, 169, 171, 173, 175, 177,
+ 179, 181, 183, 185, 187, 189, 193,
+ 195, 197, 199, 201, 203, 205, 207,
+ 209, 211, 213, 215, 217, 219, 221,
+ 225, 227, 229, 233
+ };
int i, n_chan, batch_size, idx = 0, tx_power, last_ch;
struct mt76_connac_sku_tlv sku_tlbv;
struct mt76_power_limits limits;
@@ -1893,6 +1914,9 @@ mt76_connac_mcu_rate_txpower_band(struct mt76_phy *phy,
if (band == NL80211_BAND_2GHZ) {
n_chan = ARRAY_SIZE(chan_list_2ghz);
ch_list = chan_list_2ghz;
+ } else if (band == NL80211_BAND_6GHZ) {
+ n_chan = ARRAY_SIZE(chan_list_6ghz);
+ ch_list = chan_list_6ghz;
} else {
n_chan = ARRAY_SIZE(chan_list_5ghz);
ch_list = chan_list_5ghz;
@@ -1901,13 +1925,13 @@ mt76_connac_mcu_rate_txpower_band(struct mt76_phy *phy,

if (!phy->cap.has_5ghz)
last_ch = chan_list_2ghz[n_chan - 1];
+ else if (phy->cap.has_6ghz)
+ last_ch = chan_list_6ghz[n_chan - 1];
else
last_ch = chan_list_5ghz[n_chan - 1];

for (i = 0; i < batch_size; i++) {
- struct mt76_connac_tx_power_limit_tlv tx_power_tlv = {
- .band = band == NL80211_BAND_2GHZ ? 1 : 2,
- };
+ struct mt76_connac_tx_power_limit_tlv tx_power_tlv = {};
int j, err, msg_len, num_ch;
struct sk_buff *skb;

@@ -1923,6 +1947,18 @@ mt76_connac_mcu_rate_txpower_band(struct mt76_phy *phy,
memcpy(tx_power_tlv.alpha2, dev->alpha2, sizeof(dev->alpha2));
tx_power_tlv.n_chan = num_ch;

+ switch (band) {
+ case NL80211_BAND_2GHZ:
+ tx_power_tlv.band = 1;
+ break;
+ case NL80211_BAND_6GHZ:
+ tx_power_tlv.band = 3;
+ break;
+ default:
+ tx_power_tlv.band = 2;
+ break;
+ }
+
for (j = 0; j < num_ch; j++, idx++) {
struct ieee80211_channel chan = {
.hw_value = ch_list[idx],
@@ -1973,6 +2009,12 @@ int mt76_connac_mcu_set_rate_txpower(struct mt76_phy *phy)
if (err < 0)
return err;
}
+ if (phy->cap.has_6ghz) {
+ err = mt76_connac_mcu_rate_txpower_band(phy,
+ NL80211_BAND_6GHZ);
+ if (err < 0)
+ return err;
+ }

return 0;
}
diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h
index cb36dd39221c..0f11574af535 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h
@@ -964,7 +964,7 @@ struct mt76_connac_tx_power_limit_tlv {
__le16 len;
/* DW1 - cmd hint */
u8 n_chan; /* # channel */
- u8 band; /* 2.4GHz - 5GHz */
+ u8 band; /* 2.4GHz - 5GHz - 6GHz */
u8 last_msg;
u8 pad1;
/* DW3 */
--
2.31.1

2021-08-24 10:26:28

by Lorenzo Bianconi

[permalink] [raw]
Subject: [PATCH 9/9] mt76: mt7921: add 6GHz support

Unlock 6GHz band if supported by the device. Configure HE 6G
capabilities.

Tested-by: Deren Wu <[email protected]>
Signed-off-by: Lorenzo Bianconi <[email protected]>
---
.../net/wireless/mediatek/mt76/mt7921/mac.c | 33 ++++++++++------
.../net/wireless/mediatek/mt76/mt7921/main.c | 39 ++++++++++++++++++-
.../net/wireless/mediatek/mt76/mt7921/mcu.c | 6 ++-
.../wireless/mediatek/mt76/mt7921/mt7921.h | 2 +-
4 files changed, 64 insertions(+), 16 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
index 55b7a52cd232..7eee67a4d184 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
@@ -355,7 +355,14 @@ mt7921_get_status_freq_info(struct mt7921_dev *dev, struct mt76_phy *mphy,
return;
}

- status->band = chfreq <= 14 ? NL80211_BAND_2GHZ : NL80211_BAND_5GHZ;
+ if (chfreq > 180) {
+ status->band = NL80211_BAND_6GHZ;
+ chfreq = (chfreq - 181) * 4 + 1;
+ } else if (chfreq > 14) {
+ status->band = NL80211_BAND_5GHZ;
+ } else {
+ status->band = NL80211_BAND_2GHZ;
+ }
status->freq = ieee80211_channel_to_frequency(chfreq, status->band);
}

@@ -441,10 +448,17 @@ mt7921_mac_fill_rx(struct mt7921_dev *dev, struct sk_buff *skb)

mt7921_get_status_freq_info(dev, mphy, status, chfreq);

- if (status->band == NL80211_BAND_5GHZ)
+ switch (status->band) {
+ case NL80211_BAND_5GHZ:
sband = &mphy->sband_5g.sband;
- else
+ break;
+ case NL80211_BAND_6GHZ:
+ sband = &mphy->sband_6g.sband;
+ break;
+ default:
sband = &mphy->sband_2g.sband;
+ break;
+ }

if (!sband->channels)
return -EINVAL;
@@ -994,7 +1008,7 @@ mt7921_tx_check_aggr(struct ieee80211_sta *sta, __le32 *txwi)
u16 fc, tid;
u32 val;

- if (!sta || !sta->ht_cap.ht_supported)
+ if (!sta || !(sta->ht_cap.ht_supported || sta->he_cap.has_he))
return;

tid = FIELD_GET(MT_TXD1_TID, le32_to_cpu(txwi[1]));
@@ -1397,17 +1411,12 @@ void mt7921_mac_set_timing(struct mt7921_phy *phy)
FIELD_PREP(MT_TIMEOUT_VAL_CCA, 48);
u32 ofdm = FIELD_PREP(MT_TIMEOUT_VAL_PLCP, 60) |
FIELD_PREP(MT_TIMEOUT_VAL_CCA, 28);
- int sifs, offset;
- bool is_5ghz = phy->mt76->chandef.chan->band == NL80211_BAND_5GHZ;
+ bool is_2ghz = phy->mt76->chandef.chan->band == NL80211_BAND_2GHZ;
+ int sifs = is_2ghz ? 10 : 16, offset;

if (!test_bit(MT76_STATE_RUNNING, &phy->mt76->state))
return;

- if (is_5ghz)
- sifs = 16;
- else
- sifs = 10;
-
mt76_set(dev, MT_ARB_SCR(0),
MT_ARB_SCR_TX_DISABLE | MT_ARB_SCR_RX_DISABLE);
udelay(1);
@@ -1424,7 +1433,7 @@ void mt7921_mac_set_timing(struct mt7921_phy *phy)
FIELD_PREP(MT_IFS_SIFS, sifs) |
FIELD_PREP(MT_IFS_SLOT, phy->slottime));

- if (phy->slottime < 20 || is_5ghz)
+ if (phy->slottime < 20 || !is_2ghz)
val = MT7921_CFEND_RATE_DEFAULT;
else
val = MT7921_CFEND_RATE_11B;
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/main.c b/drivers/net/wireless/mediatek/mt76/mt7921/main.c
index 217ed7055aa0..cd3974b6ba8f 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7921/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7921/main.c
@@ -72,7 +72,7 @@ mt7921_init_he_caps(struct mt7921_phy *phy, enum nl80211_band band,
if (band == NL80211_BAND_2GHZ)
he_cap_elem->phy_cap_info[0] =
IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_IN_2G;
- else if (band == NL80211_BAND_5GHZ)
+ else
he_cap_elem->phy_cap_info[0] =
IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G;

@@ -93,7 +93,7 @@ mt7921_init_he_caps(struct mt7921_phy *phy, enum nl80211_band band,
if (band == NL80211_BAND_2GHZ)
he_cap_elem->phy_cap_info[0] |=
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] |=
IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_RU_MAPPING_IN_5G;

@@ -142,6 +142,32 @@ mt7921_init_he_caps(struct mt7921_phy *phy, enum nl80211_band band,
he_cap_elem->phy_cap_info[9] |=
IEEE80211_HE_PHY_CAP9_NOMIMAL_PKT_PADDING_16US;
}
+
+ if (band == NL80211_BAND_6GHZ) {
+ struct ieee80211_supported_band *sband =
+ &phy->mt76->sband_5g.sband;
+ struct ieee80211_sta_vht_cap *vht_cap = &sband->vht_cap;
+ struct ieee80211_sta_ht_cap *ht_cap = &sband->ht_cap;
+ u32 exp;
+ u16 cap;
+
+ cap = u16_encode_bits(ht_cap->ampdu_density,
+ IEEE80211_HE_6GHZ_CAP_MIN_MPDU_START);
+ exp = u32_get_bits(vht_cap->cap,
+ IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK);
+ cap |= u16_encode_bits(exp,
+ IEEE80211_HE_6GHZ_CAP_MAX_AMPDU_LEN_EXP);
+ exp = u32_get_bits(vht_cap->cap,
+ IEEE80211_VHT_CAP_MAX_MPDU_MASK);
+ cap |= u16_encode_bits(exp,
+ IEEE80211_HE_6GHZ_CAP_MAX_MPDU_LEN);
+ if (vht_cap->cap & IEEE80211_VHT_CAP_TX_ANTENNA_PATTERN)
+ cap |= IEEE80211_HE_6GHZ_CAP_TX_ANTPAT_CONS;
+ if (vht_cap->cap & IEEE80211_VHT_CAP_RX_ANTENNA_PATTERN)
+ cap |= IEEE80211_HE_6GHZ_CAP_RX_ANTPAT_CONS;
+
+ data->he_6ghz_capa.capa = cpu_to_le16(cap);
+ }
idx++;
}

@@ -170,6 +196,15 @@ void mt7921_set_stream_he_caps(struct mt7921_phy *phy)
band = &phy->mt76->sband_5g.sband;
band->iftype_data = data;
band->n_iftype_data = n;
+
+ if (phy->mt76->cap.has_6ghz) {
+ data = phy->iftype[NL80211_BAND_6GHZ];
+ n = mt7921_init_he_caps(phy, NL80211_BAND_6GHZ, data);
+
+ band = &phy->mt76->sband_6g.sband;
+ band->iftype_data = data;
+ band->n_iftype_data = n;
+ }
}
}

diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c
index f49fc8078125..34038f182bb0 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c
@@ -1028,9 +1028,13 @@ int mt7921_mcu_set_chan_info(struct mt7921_phy *phy, int cmd)
.tx_streams_num = hweight8(phy->mt76->antenna_mask),
.rx_streams = phy->mt76->antenna_mask,
.band_idx = phy != &dev->phy,
- .channel_band = chandef->chan->band,
};

+ if (chandef->chan->band == NL80211_BAND_6GHZ)
+ req.channel_band = 2;
+ else
+ req.channel_band = chandef->chan->band;
+
if (dev->mt76.hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)
req.switch_reason = CH_SWITCH_SCAN_BYPASS_DPD;
else if ((chandef->chan->flags & IEEE80211_CHAN_RADAR) &&
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h b/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h
index a6caca73fdda..856035e0a5b7 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h
@@ -111,7 +111,7 @@ struct mt7921_phy {
struct mt76_phy *mt76;
struct mt7921_dev *dev;

- struct ieee80211_sband_iftype_data iftype[2][NUM_NL80211_IFTYPES];
+ struct ieee80211_sband_iftype_data iftype[NUM_NL80211_BANDS][NUM_NL80211_IFTYPES];

u32 rxfilter;
u64 omac_mask;
--
2.31.1