| 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 |
| |