blob: 841aaba94d55b0688612b3ace4475688c8e89994 [file] [log] [blame]
From 155e1bd8b7933deef463abc30f7d375761b93055 Mon Sep 17 00:00:00 2001
From: Shayne Chen <shayne.chen@mediatek.com>
Date: Thu, 28 Mar 2024 18:50:04 +0800
Subject: [PATCH 105/116] wifi: mt76: mt7996: temp support for single wiphy
Add temporal single wiphy for simultaneously supporting MLD and legacy
interfaces.
Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
---
mac80211.c | 11 +------
mt76.h | 11 +------
mt7996/eeprom.c | 6 ----
mt7996/init.c | 23 ++++++++++---
mt7996/mac.c | 5 +--
mt7996/main.c | 88 ++++++++++++++++++++++++++++++-------------------
mt7996/mt7996.h | 14 ++++----
7 files changed, 81 insertions(+), 77 deletions(-)
diff --git a/mac80211.c b/mac80211.c
index dad659ecb..20ab1db4d 100644
--- a/mac80211.c
+++ b/mac80211.c
@@ -823,13 +823,9 @@ EXPORT_SYMBOL_GPL(mt76_has_tx_pending);
struct mt76_channel_state *
mt76_channel_state(struct mt76_phy *phy, struct ieee80211_channel *c)
{
- struct mt76_phy *ori_phy = phy;
struct mt76_sband *msband;
int idx;
- if (phy->main_phy)
- phy = phy->main_phy;
-begin:
if (c->band == NL80211_BAND_2GHZ)
msband = &phy->sband_2g;
else if (c->band == NL80211_BAND_6GHZ)
@@ -838,11 +834,6 @@ begin:
msband = &phy->sband_5g;
idx = c - &msband->sband.channels[0];
- /* TODO: mlo: this is a temp solution, need to come up with a more clever one */
- if (idx < 0 || idx >= msband->sband.n_channels) {
- phy = ori_phy;
- goto begin;
- }
return &msband->chan[idx];
}
EXPORT_SYMBOL_GPL(mt76_channel_state);
@@ -1081,7 +1072,7 @@ mt76_rx_convert(struct mt76_dev *dev, struct sk_buff *skb,
}
*sta = wcid_to_sta(mstat.wcid);
- *hw = mt76_main_hw(dev->phys[mstat.phy_idx]);
+ *hw = mt76_phy_hw(dev, mstat.phy_idx);
if ((mstat.flag & RX_FLAG_8023) || ieee80211_is_data_qos(hdr->frame_control)) {
struct mt76_phy *phy = mt76_dev_phy(dev, mstat.phy_idx);
diff --git a/mt76.h b/mt76.h
index 64ea323d8..b77a2f76b 100644
--- a/mt76.h
+++ b/mt76.h
@@ -833,8 +833,8 @@ struct mt76_vif {
struct mt76_phy {
struct ieee80211_hw *hw;
+ struct ieee80211_hw *ori_hw;
struct mt76_dev *dev;
- struct mt76_phy *main_phy;
void *priv;
unsigned long state;
@@ -1326,15 +1326,6 @@ mt76_phy_hw(struct mt76_dev *dev, u8 phy_idx)
return mt76_dev_phy(dev, phy_idx)->hw;
}
-static inline struct ieee80211_hw *
-mt76_main_hw(struct mt76_phy *phy)
-{
- if (phy->main_phy)
- return mt76_dev_phy(phy->dev, phy->main_phy->band_idx)->hw;
-
- return mt76_dev_phy(phy->dev, phy->band_idx)->hw;
-}
-
static inline u8 *
mt76_get_txwi_ptr(struct mt76_dev *dev, struct mt76_txwi_cache *t)
{
diff --git a/mt7996/eeprom.c b/mt7996/eeprom.c
index 0393e93bf..51455d877 100644
--- a/mt7996/eeprom.c
+++ b/mt7996/eeprom.c
@@ -387,12 +387,6 @@ static int mt7996_eeprom_parse_band_config(struct mt7996_phy *phy)
break;
}
- /* TODO: for MLO, we enable all band capabilities */
- phy->mt76->cap.has_2ghz = true;
- phy->mt76->cap.has_5ghz = true;
- if (is_mt7996(&phy->dev->mt76))
- phy->mt76->cap.has_6ghz = true;
-
return ret;
}
diff --git a/mt7996/init.c b/mt7996/init.c
index c6eb6a5c2..f374119f6 100644
--- a/mt7996/init.c
+++ b/mt7996/init.c
@@ -18,13 +18,13 @@ static const struct ieee80211_iface_limit if_limits[] = {
.max = 1,
.types = BIT(NL80211_IFTYPE_ADHOC)
}, {
- .max = 16,
+ .max = 16 * 3,
.types = BIT(NL80211_IFTYPE_AP)
#ifdef CONFIG_MAC80211_MESH
| BIT(NL80211_IFTYPE_MESH_POINT)
#endif
}, {
- .max = MT7996_MAX_INTERFACES,
+ .max = MT7996_MAX_INTERFACES * 3,
.types = BIT(NL80211_IFTYPE_STATION)
}
};
@@ -33,7 +33,7 @@ static const struct ieee80211_iface_combination if_comb[] = {
{
.limits = if_limits,
.n_limits = ARRAY_SIZE(if_limits),
- .max_interfaces = MT7996_MAX_INTERFACES,
+ .max_interfaces = MT7996_MAX_INTERFACES * 3,
.num_different_channels = 3,
.beacon_int_infra_match = true,
/*
@@ -795,6 +795,10 @@ static int mt7996_register_phy(struct mt7996_dev *dev, struct mt7996_phy *phy,
mtk_wed_device_start(&dev->mt76.mmio.wed_hif2, MT_INT_TX_RX_DONE_EXT);
}
+ /* TODO: FIXME: force to use single wiphy, need to rework init flow */
+ phy->mt76->ori_hw = mphy->hw;
+ mphy->hw = dev->phy.mt76->hw;
+
return 0;
error:
@@ -811,6 +815,9 @@ mt7996_unregister_phy(struct mt7996_phy *phy, enum mt76_band_id band)
if (!phy)
return;
+ /* TODO: FIXME: temp for single wiphy support */
+ phy->mt76->hw = phy->mt76->ori_hw;
+
mt7996_unregister_thermal(phy);
mphy = phy->dev->mt76.phys[band];
@@ -1679,6 +1686,12 @@ int mt7996_register_device(struct mt7996_dev *dev)
if (ret)
return ret;
+ hw->wiphy->bands[NL80211_BAND_2GHZ] = &dev->phy.mt76->sband_2g.sband;
+ if (mt7996_phy2(dev))
+ hw->wiphy->bands[NL80211_BAND_5GHZ] = &mt7996_phy2(dev)->mt76->sband_5g.sband;
+ if (mt7996_phy3(dev))
+ hw->wiphy->bands[NL80211_BAND_6GHZ] = &mt7996_phy3(dev)->mt76->sband_6g.sband;
+
ieee80211_queue_work(mt76_hw(dev), &dev->init_work);
dev->recovery.hw_init_done = true;
@@ -1708,11 +1721,11 @@ error:
void mt7996_unregister_device(struct mt7996_dev *dev)
{
cancel_work_sync(&dev->wed_rro.work);
- mt7996_unregister_phy(mt7996_phy3(dev), MT_BAND2);
- mt7996_unregister_phy(mt7996_phy2(dev), MT_BAND1);
mt7996_unregister_thermal(&dev->phy);
mt7996_coredump_unregister(dev);
mt76_unregister_device(&dev->mt76);
+ mt7996_unregister_phy(mt7996_phy2(dev), MT_BAND1);
+ mt7996_unregister_phy(mt7996_phy3(dev), MT_BAND2);
mt7996_wed_rro_free(dev);
mt7996_mcu_exit(dev);
mt7996_tx_token_put(dev);
diff --git a/mt7996/mac.c b/mt7996/mac.c
index 3141fe4e4..e6db1765f 100644
--- a/mt7996/mac.c
+++ b/mt7996/mac.c
@@ -2403,10 +2403,7 @@ void mt7996_mac_work(struct work_struct *work)
mt76_tx_status_check(mdev, false);
- if (mphy->main_phy && !test_bit(MT76_STATE_RUNNING, &mphy->main_phy->state))
- return;
-
- ieee80211_queue_delayed_work(mt76_main_hw(mphy), &mphy->mac_work,
+ ieee80211_queue_delayed_work(mphy->hw, &mphy->mac_work,
MT7996_WATCHDOG_TIME);
}
diff --git a/mt7996/main.c b/mt7996/main.c
index a38d77390..b9cc5a2e5 100644
--- a/mt7996/main.c
+++ b/mt7996/main.c
@@ -140,6 +140,10 @@ static int mt7996_start(struct ieee80211_hw *hw)
struct mt7996_dev *dev = mt7996_hw_dev(hw);
int ret;
+ /* only allow settings from hw0 */
+ if (hw != dev->phy.mt76->hw)
+ return -1;
+
flush_work(&dev->init_work);
mutex_lock(&dev->mt76.mutex);
@@ -154,6 +158,10 @@ static void mt7996_stop(struct ieee80211_hw *hw)
struct mt7996_dev *dev = mt7996_hw_dev(hw);
int band;
+ /* only allow settings from hw0 */
+ if (hw != dev->phy.mt76->hw)
+ return;
+
cancel_delayed_work_sync(&dev->scs_work);
for (band = 0; band < NUM_NL80211_BANDS; band++) {
@@ -173,7 +181,6 @@ static void mt7996_stop(struct ieee80211_hw *hw)
mutex_lock(&dev->mt76.mutex);
mt7996_mcu_set_radio_en(phy, false);
clear_bit(MT76_STATE_RUNNING, &phy->mt76->state);
- phy->mt76->main_phy = NULL;
mutex_unlock(&dev->mt76.mutex);
}
}
@@ -446,8 +453,11 @@ static int mt7996_add_interface(struct ieee80211_hw *hw,
mvif->dev = dev;
mvif->hw = hw;
mvif->sta.vif = mvif;
+ /* TODO: temporaily set this to prevent some crashes */
+ mvif->deflink.phy = phy;
- ret = mt7996_add_bss_conf(phy, vif, &vif->bss_conf);
+ if (vif->type == NL80211_IFTYPE_STATION)
+ ret = mt7996_add_bss_conf(phy, vif, &vif->bss_conf);
mutex_unlock(&dev->mt76.mutex);
return ret;
@@ -543,10 +553,9 @@ out:
clear_bit(MT76_RESET, &phy->mt76->state);
mutex_unlock(&dev->mt76.mutex);
- if (phy->mt76 == phy->mt76->main_phy)
- mt76_txq_schedule_all(phy->mt76);
+ mt76_txq_schedule_all(phy->mt76);
- ieee80211_queue_delayed_work(mt76_main_hw(phy->mt76),
+ ieee80211_queue_delayed_work(phy->mt76->hw,
&phy->mt76->mac_work,
MT7996_WATCHDOG_TIME);
@@ -557,11 +566,11 @@ int mt7996_set_channel(struct mt7996_phy *phy, struct cfg80211_chan_def *chandef
{
int ret;
- ieee80211_stop_queues(mt76_main_hw(phy->mt76));
+ ieee80211_stop_queues(phy->mt76->hw);
ret = __mt7996_set_channel(phy, chandef);
if (ret)
return ret;
- ieee80211_wake_queues(mt76_main_hw(phy->mt76));
+ ieee80211_wake_queues(phy->mt76->hw);
return 0;
}
@@ -769,9 +778,6 @@ static void mt7996_configure_filter(struct ieee80211_hw *hw,
continue;
tmp = dev->mt76.phys[band]->priv;
- if (tmp->mt76->main_phy != phy->mt76)
- continue;
-
tmp->rxfilter = phy->rxfilter;
mt76_wr(dev, MT_WF_RFCR(tmp->mt76->band_idx), phy->rxfilter);
@@ -1576,9 +1582,11 @@ static int
mt7996_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant)
{
struct mt7996_dev *dev = mt7996_hw_dev(hw);
- struct mt7996_phy *phy = mt7996_hw_phy(hw);
- int max_nss = hweight8(hw->wiphy->available_antennas_tx);
- u8 band_idx = phy->mt76->band_idx, shift = dev->chainshift[band_idx];
+ int band, max_nss = hweight8(hw->wiphy->available_antennas_tx);
+
+ /* only allow settings from hw0 */
+ if (hw != dev->phy.mt76->hw)
+ return 0;
if (!tx_ant || tx_ant != rx_ant || ffs(tx_ant) > max_nss)
return -EINVAL;
@@ -1588,20 +1596,34 @@ mt7996_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant)
mutex_lock(&dev->mt76.mutex);
- phy->mt76->antenna_mask = tx_ant;
+ for (band = 0; band < NUM_NL80211_BANDS; band++) {
+ struct mt7996_phy *phy;
+ u8 band_idx, shift;
+
+ if (!hw->wiphy->bands[band])
+ continue;
- /* restore to the origin chainmask which might have auxiliary path */
- if (hweight8(tx_ant) == max_nss && band_idx < MT_BAND2)
- phy->mt76->chainmask = ((dev->chainmask >> shift) &
- (BIT(dev->chainshift[band_idx + 1] - shift) - 1)) << shift;
- else if (hweight8(tx_ant) == max_nss)
- phy->mt76->chainmask = (dev->chainmask >> shift) << shift;
- else
- phy->mt76->chainmask = tx_ant << shift;
+ phy = mt7996_band_phy(hw, band);
+ if (!phy)
+ continue;
- mt76_set_stream_caps(phy->mt76, true);
- mt7996_set_stream_vht_txbf_caps(phy);
- mt7996_set_stream_he_eht_caps(phy);
+ phy->mt76->antenna_mask = tx_ant;
+ band_idx = phy->mt76->band_idx;
+ shift = dev->chainshift[band_idx];
+
+ /* restore to the origin chainmask which might have auxiliary path */
+ if (hweight8(tx_ant) == max_nss && band_idx < MT_BAND2)
+ phy->mt76->chainmask = ((dev->chainmask >> shift) &
+ (BIT(dev->chainshift[band_idx + 1] - shift) - 1)) << shift;
+ else if (hweight8(tx_ant) == max_nss)
+ phy->mt76->chainmask = (dev->chainmask >> shift) << shift;
+ else
+ phy->mt76->chainmask = tx_ant << shift;
+
+ mt76_set_stream_caps(phy->mt76, true);
+ mt7996_set_stream_vht_txbf_caps(phy);
+ mt7996_set_stream_he_eht_caps(phy);
+ }
mutex_unlock(&dev->mt76.mutex);
@@ -2243,7 +2265,7 @@ mt7996_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
phy->scan_chan_idx = 0;
if (vif->type == NL80211_IFTYPE_STATION && !ieee80211_vif_is_mld(vif) &&
(phy->mt76 != mvif->deflink.phy->mt76)) {
- phy->mt76->main_phy = hw->priv;
+ // phy->mt76->main_phy = hw->priv;
mt7996_remove_bss_conf(vif, &vif->bss_conf, &mvif->deflink);
ret = mt7996_add_bss_conf(phy, vif, &vif->bss_conf);
@@ -2254,7 +2276,7 @@ mt7996_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
}
mutex_unlock(&phy->dev->mt76.mutex);
- ieee80211_queue_delayed_work(mt76_main_hw(phy->mt76), &phy->scan_work, 0);
+ ieee80211_queue_delayed_work(phy->mt76->hw, &phy->scan_work, 0);
return 0;
}
@@ -2262,7 +2284,7 @@ mt7996_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
static void
mt7996_cancel_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
{
- struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
+ // struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
int band;
for (band = 0; band < NUM_NL80211_BANDS; band++) {
@@ -2272,17 +2294,16 @@ mt7996_cancel_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
continue;
phy = mt7996_band_phy(hw, band);
- if (!(test_bit(MT76_SCANNING, &phy->mt76->state) &&
- phy->mt76->main_phy == hw->priv))
+ if (!test_bit(MT76_SCANNING, &phy->mt76->state))
continue;
cancel_delayed_work_sync(&phy->scan_work);
mutex_lock(&phy->dev->mt76.mutex);
mt7996_scan_complete(phy, true);
- if (vif->type == NL80211_IFTYPE_STATION && !ieee80211_vif_is_mld(vif) &&
- (phy->mt76 != mvif->deflink.phy->mt76))
- phy->mt76->main_phy = NULL;
+ // if (vif->type == NL80211_IFTYPE_STATION && !ieee80211_vif_is_mld(vif) &&
+ // (phy->mt76 != mvif->deflink.phy->mt76))
+ // phy->mt76->main_phy = NULL;
mutex_unlock(&phy->dev->mt76.mutex);
}
}
@@ -2297,7 +2318,6 @@ mt7996_add_chanctx(struct ieee80211_hw *hw, struct ieee80211_chanctx_conf *conf)
wiphy_info(hw->wiphy, "%s: add %u\n", __func__, conf->def.chan->hw_value);
mutex_lock(&phy->dev->mt76.mutex);
- phy->mt76->main_phy = hw->priv;
if (ctx->assigned) {
mutex_unlock(&phy->dev->mt76.mutex);
return -ENOSPC;
diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
index 39aa3ee5b..0444ae58e 100644
--- a/mt7996/mt7996.h
+++ b/mt7996/mt7996.h
@@ -794,21 +794,19 @@ mt7996_get_background_radar_cap(struct mt7996_dev *dev)
static inline struct mt7996_phy *
mt7996_band_phy(struct ieee80211_hw *hw, enum nl80211_band band)
{
- struct mt76_phy *phy = hw->priv;
-
- if (!(hw->wiphy->flags & WIPHY_FLAG_SUPPORTS_MLO))
- return phy->priv;
+ struct mt76_dev *dev = hw->priv;
+ struct mt76_phy *phy;
/* TODO: mlo: temporarily hardcode */
if (band == NL80211_BAND_6GHZ)
- phy = phy->dev->phys[MT_BAND2];
+ phy = dev->phys[MT_BAND2];
else if (band == NL80211_BAND_5GHZ)
- phy = phy->dev->phys[MT_BAND1];
+ phy = dev->phys[MT_BAND1];
else
- phy = phy->dev->phys[MT_BAND0];
+ phy = dev->phys[MT_BAND0];
if (!phy)
- phy = hw->priv;
+ return NULL;
return phy->priv;
}
--
2.39.2