Commit edf9dab8 authored by Lorenzo Bianconi's avatar Lorenzo Bianconi Committed by Felix Fietkau

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: default avatarDeren Wu <deren.wu@mediatek.com>
Signed-off-by: default avatarLorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: default avatarFelix Fietkau <nbd@nbd.name>
parent bebd3681
...@@ -20,6 +20,13 @@ ...@@ -20,6 +20,13 @@
.max_power = 30, \ .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[] = { static const struct ieee80211_channel mt76_channels_2ghz[] = {
CHAN2G(1, 2412), CHAN2G(1, 2412),
CHAN2G(2, 2417), CHAN2G(2, 2417),
...@@ -70,6 +77,72 @@ static const struct ieee80211_channel mt76_channels_5ghz[] = { ...@@ -70,6 +77,72 @@ static const struct ieee80211_channel mt76_channels_5ghz[] = {
CHAN5G(173, 5865), 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[] = { static const struct ieee80211_tpt_blink mt76_tpt_blink[] = {
{ .throughput = 0 * 1024, .blink_time = 334 }, { .throughput = 0 * 1024, .blink_time = 334 },
{ .throughput = 1 * 1024, .blink_time = 260 }, { .throughput = 1 * 1024, .blink_time = 260 },
...@@ -194,13 +267,16 @@ void mt76_set_stream_caps(struct mt76_phy *phy, bool vht) ...@@ -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); mt76_init_stream_cap(phy, &phy->sband_2g.sband, false);
if (phy->cap.has_5ghz) if (phy->cap.has_5ghz)
mt76_init_stream_cap(phy, &phy->sband_5g.sband, vht); 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); EXPORT_SYMBOL_GPL(mt76_set_stream_caps);
static int static int
mt76_init_sband(struct mt76_phy *phy, struct mt76_sband *msband, mt76_init_sband(struct mt76_phy *phy, struct mt76_sband *msband,
const struct ieee80211_channel *chan, int n_chan, 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_supported_band *sband = &msband->sband;
struct ieee80211_sta_vht_cap *vht_cap; struct ieee80211_sta_vht_cap *vht_cap;
...@@ -224,6 +300,9 @@ mt76_init_sband(struct mt76_phy *phy, struct mt76_sband *msband, ...@@ -224,6 +300,9 @@ mt76_init_sband(struct mt76_phy *phy, struct mt76_sband *msband,
sband->bitrates = rates; sband->bitrates = rates;
sband->n_bitrates = n_rates; sband->n_bitrates = n_rates;
if (!ht)
return 0;
ht_cap = &sband->ht_cap; ht_cap = &sband->ht_cap;
ht_cap->ht_supported = true; ht_cap->ht_supported = true;
ht_cap->cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40 | 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, ...@@ -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, return mt76_init_sband(phy, &phy->sband_2g, mt76_channels_2ghz,
ARRAY_SIZE(mt76_channels_2ghz), rates, ARRAY_SIZE(mt76_channels_2ghz), rates,
n_rates, false); n_rates, true, false);
} }
static int static int
...@@ -271,7 +350,18 @@ mt76_init_sband_5g(struct mt76_phy *phy, struct ieee80211_rate *rates, ...@@ -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, return mt76_init_sband(phy, &phy->sband_5g, mt76_channels_5ghz,
ARRAY_SIZE(mt76_channels_5ghz), rates, 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 static void
...@@ -396,9 +486,16 @@ int mt76_register_phy(struct mt76_phy *phy, bool vht, ...@@ -396,9 +486,16 @@ int mt76_register_phy(struct mt76_phy *phy, bool vht,
return ret; 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); wiphy_read_of_freq_limits(phy->hw->wiphy);
mt76_check_sband(phy, &phy->sband_2g, NL80211_BAND_2GHZ); 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_5g, NL80211_BAND_5GHZ);
mt76_check_sband(phy, &phy->sband_6g, NL80211_BAND_6GHZ);
ret = ieee80211_register_hw(phy->hw); ret = ieee80211_register_hw(phy->hw);
if (ret) if (ret)
...@@ -506,9 +603,16 @@ int mt76_register_device(struct mt76_dev *dev, bool vht, ...@@ -506,9 +603,16 @@ int mt76_register_device(struct mt76_dev *dev, bool vht,
return ret; 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); 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_2g, NL80211_BAND_2GHZ);
mt76_check_sband(&dev->phy, &phy->sband_5g, NL80211_BAND_5GHZ); 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)) { if (IS_ENABLED(CONFIG_MT76_LEDS)) {
ret = mt76_led_init(dev); ret = mt76_led_init(dev);
...@@ -653,6 +757,8 @@ mt76_channel_state(struct mt76_phy *phy, struct ieee80211_channel *c) ...@@ -653,6 +757,8 @@ mt76_channel_state(struct mt76_phy *phy, struct ieee80211_channel *c)
if (c->band == NL80211_BAND_2GHZ) if (c->band == NL80211_BAND_2GHZ)
msband = &phy->sband_2g; msband = &phy->sband_2g;
else if (c->band == NL80211_BAND_6GHZ)
msband = &phy->sband_6g;
else else
msband = &phy->sband_5g; msband = &phy->sband_5g;
...@@ -728,10 +834,16 @@ int mt76_get_survey(struct ieee80211_hw *hw, int idx, ...@@ -728,10 +834,16 @@ int mt76_get_survey(struct ieee80211_hw *hw, int idx,
if (idx == 0 && dev->drv->update_survey) if (idx == 0 && dev->drv->update_survey)
mt76_update_survey(phy); mt76_update_survey(phy);
sband = &phy->sband_2g; if (idx >= phy->sband_2g.sband.n_channels +
if (idx >= sband->sband.n_channels) { phy->sband_5g.sband.n_channels) {
idx -= sband->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; sband = &phy->sband_5g;
} else {
sband = &phy->sband_2g;
} }
if (idx >= sband->sband.n_channels) { if (idx >= sband->sband.n_channels) {
...@@ -1286,7 +1398,7 @@ int mt76_get_rate(struct mt76_dev *dev, ...@@ -1286,7 +1398,7 @@ int mt76_get_rate(struct mt76_dev *dev,
int i, offset = 0, len = sband->n_bitrates; int i, offset = 0, len = sband->n_bitrates;
if (cck) { if (cck) {
if (sband == &dev->phy.sband_5g.sband) if (sband != &dev->phy.sband_2g.sband)
return 0; return 0;
idx &= ~BIT(2); /* short preamble */ idx &= ~BIT(2); /* short preamble */
...@@ -1358,7 +1470,7 @@ u16 mt76_calculate_default_rate(struct mt76_phy *phy, int rateidx) ...@@ -1358,7 +1470,7 @@ u16 mt76_calculate_default_rate(struct mt76_phy *phy, int rateidx)
int offset = 0; int offset = 0;
struct ieee80211_rate *rate; struct ieee80211_rate *rate;
if (phy->chandef.chan->band == NL80211_BAND_5GHZ) if (phy->chandef.chan->band != NL80211_BAND_2GHZ)
offset = 4; offset = 4;
/* pick the lowest rate for hidden nodes */ /* pick the lowest rate for hidden nodes */
......
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