blob: fed26156bfe8efd4f2b6a4a942765e5270a6b63f [file] [log] [blame]
From d1ceb708475e11cf159886d4c9e6ce78c4d3030d Mon Sep 17 00:00:00 2001
From: Shayne Chen <shayne.chen@mediatek.com>
Date: Fri, 8 Dec 2023 18:08:13 +0800
Subject: [PATCH 093/223] mtk: mt76: mt7996: handle mapping for hw and vif
We have several temporal workarounds for ieee80211_hw and mt76_phy
mappings. For legacy MBSS cases, we also need a method to do the
hw and vif mappings.
This is a preliminary patch to add MLO support for mt7996 chipsets.
Co-developed-by: Bo Jiao <Bo.Jiao@mediatek.com>
Signed-off-by: Bo Jiao <Bo.Jiao@mediatek.com>
Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
---
dma.c | 2 +-
mac80211.c | 2 +-
mt76.h | 14 ++++++++++++--
mt7996/mac.c | 24 +++++++++++++++++++++++-
mt7996/main.c | 1 +
mt7996/mcu.c | 4 ++--
mt7996/mmio.c | 1 +
mt7996/mt7996.h | 3 +++
tx.c | 4 ++--
9 files changed, 46 insertions(+), 9 deletions(-)
diff --git a/dma.c b/dma.c
index 38701c71..3f1fb6c2 100644
--- a/dma.c
+++ b/dma.c
@@ -685,7 +685,7 @@ free:
free_skb:
status.skb = tx_info.skb;
- hw = mt76_tx_status_get_hw(dev, tx_info.skb);
+ hw = mt76_tx_status_get_hw(dev, tx_info.skb, wcid);
spin_lock_bh(&dev->rx_lock);
ieee80211_tx_status_ext(hw, &status);
spin_unlock_bh(&dev->rx_lock);
diff --git a/mac80211.c b/mac80211.c
index 03632279..b1af346a 100644
--- a/mac80211.c
+++ b/mac80211.c
@@ -1546,7 +1546,7 @@ void mt76_wcid_cleanup(struct mt76_dev *dev, struct mt76_wcid *wcid)
spin_unlock_bh(&phy->tx_lock);
while ((skb = __skb_dequeue(&list)) != NULL) {
- hw = mt76_tx_status_get_hw(dev, skb);
+ hw = mt76_tx_status_get_hw(dev, skb, wcid);
ieee80211_free_txskb(hw, skb);
}
}
diff --git a/mt76.h b/mt76.h
index 9fa411cb..2dea07a3 100644
--- a/mt76.h
+++ b/mt76.h
@@ -567,6 +567,9 @@ struct mt76_driver_ops {
void (*sta_remove)(struct mt76_dev *dev, struct ieee80211_vif *vif,
struct ieee80211_sta *sta);
+
+ void (*get_hw)(struct mt76_dev *dev, struct mt76_wcid *wcid, u8 phy_idx,
+ struct ieee80211_hw **hw);
};
struct mt76_channel_state {
@@ -1602,14 +1605,21 @@ extern const struct nla_policy mt76_tm_policy[NUM_MT76_TM_ATTRS];
/* internal */
static inline struct ieee80211_hw *
-mt76_tx_status_get_hw(struct mt76_dev *dev, struct sk_buff *skb)
+mt76_tx_status_get_hw(struct mt76_dev *dev, struct sk_buff *skb,
+ struct mt76_wcid *wcid)
{
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
u8 phy_idx = (info->hw_queue & MT_TX_HW_QUEUE_PHY) >> 2;
- struct ieee80211_hw *hw = mt76_phy_hw(dev, phy_idx);
+ struct ieee80211_hw *hw;
info->hw_queue &= ~MT_TX_HW_QUEUE_PHY;
+ if (dev->drv->get_hw) {
+ dev->drv->get_hw(dev, wcid, phy_idx, &hw);
+ } else {
+ hw = mt76_phy_hw(dev, phy_idx);
+ }
+
return hw;
}
diff --git a/mt7996/mac.c b/mt7996/mac.c
index f9aa0e57..a48e4f44 100644
--- a/mt7996/mac.c
+++ b/mt7996/mac.c
@@ -2857,13 +2857,23 @@ static void mt7996_scan_check_sta(void *data, struct ieee80211_sta *sta)
void mt7996_scan_work(struct work_struct *work)
{
struct mt7996_phy *phy = container_of(work, struct mt7996_phy, scan_work.work);
- struct ieee80211_hw *hw = phy->mt76->hw;
+ struct ieee80211_vif *vif = phy->scan_vif;
+ struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
+ struct ieee80211_hw *hw = mvif->hw;
struct cfg80211_scan_request *req = phy->scan_req;
struct cfg80211_chan_def chandef = {};
int duration;
bool has_sta = false, active_scan = false;
mutex_lock(&phy->dev->mt76.mutex);
+ /* don't let non-MLD AP scan other bands */
+ if (vif->type != NL80211_IFTYPE_STATION && !ieee80211_vif_is_mld(vif) &&
+ phy != mt7996_hw_phy(hw)) {
+ mt7996_scan_complete(phy, false);
+ mutex_unlock(&phy->dev->mt76.mutex);
+ return;
+ }
+
if (phy->scan_chan_idx >= req->n_channels) {
mt7996_scan_complete(phy, false);
mutex_unlock(&phy->dev->mt76.mutex);
@@ -2923,3 +2933,15 @@ void mt7996_scan_work(struct work_struct *work)
ieee80211_queue_delayed_work(hw, &phy->scan_work, duration);
}
+
+void mt7996_get_hw(struct mt76_dev *dev, struct mt76_wcid *wcid, u8 phy_idx,
+ struct ieee80211_hw **hw)
+{
+ struct mt7996_link_sta *mlink = wcid_to_mlink(wcid);
+
+ if (mlink) {
+ *hw = mlink->sta->vif->hw;
+ } else {
+ *hw = mt76_phy_hw(dev, phy_idx);
+ }
+}
diff --git a/mt7996/main.c b/mt7996/main.c
index 01c736a9..cabd5729 100644
--- a/mt7996/main.c
+++ b/mt7996/main.c
@@ -444,6 +444,7 @@ static int mt7996_add_interface(struct ieee80211_hw *hw,
phy->monitor_vif = vif;
mvif->dev = dev;
+ mvif->hw = hw;
mvif->sta.vif = mvif;
ret = mt7996_add_bss_conf(phy, vif, &vif->bss_conf);
diff --git a/mt7996/mcu.c b/mt7996/mcu.c
index edaf8814..e7ee970b 100644
--- a/mt7996/mcu.c
+++ b/mt7996/mcu.c
@@ -2955,11 +2955,11 @@ int mt7996_mcu_beacon_inband_discov(struct mt7996_dev *dev,
if (changed & BSS_CHANGED_FILS_DISCOVERY) {
interval = conf->fils_discovery.max_interval;
- skb = ieee80211_get_fils_discovery_tmpl(hw, vif);
+ skb = ieee80211_get_fils_discovery_tmpl(mvif->hw, vif);
} else if (changed & BSS_CHANGED_UNSOL_BCAST_PROBE_RESP &&
conf->unsol_bcast_probe_resp_interval) {
interval = conf->unsol_bcast_probe_resp_interval;
- skb = ieee80211_get_unsol_bcast_probe_resp_tmpl(hw, vif);
+ skb = ieee80211_get_unsol_bcast_probe_resp_tmpl(mvif->hw, vif);
}
if (!skb) {
diff --git a/mt7996/mmio.c b/mt7996/mmio.c
index 8ac1b12a..ee5ee5a5 100644
--- a/mt7996/mmio.c
+++ b/mt7996/mmio.c
@@ -659,6 +659,7 @@ struct mt7996_dev *mt7996_mmio_probe(struct device *pdev,
.sta_remove = mt7996_mac_sta_remove,
.update_survey = mt7996_update_channel,
// .set_channel = mt7996_set_channel,
+ .get_hw = mt7996_get_hw,
};
struct mt7996_dev *dev;
struct mt76_dev *mdev;
diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
index f83308de..9dd4d478 100644
--- a/mt7996/mt7996.h
+++ b/mt7996/mt7996.h
@@ -355,6 +355,7 @@ struct mt7996_vif {
struct mt7996_sta sta;
struct mt7996_dev *dev;
+ struct ieee80211_hw *hw;
u8 master_link_id;
u8 group_mld_id;
@@ -905,6 +906,8 @@ int mt7996_init_tx_queues(struct mt7996_phy *phy, int idx,
void mt7996_init_txpower(struct mt7996_phy *phy);
int mt7996_txbf_init(struct mt7996_dev *dev);
int mt7996_get_chip_sku(struct mt7996_dev *dev);
+void mt7996_get_hw(struct mt76_dev *dev, struct mt76_wcid *wcid, u8 phy_idx,
+ struct ieee80211_hw **hw);
void mt7996_reset(struct mt7996_dev *dev);
void mt7996_coredump(struct mt7996_dev *dev, u8 state);
int mt7996_run(struct ieee80211_hw *hw);
diff --git a/tx.c b/tx.c
index a78ab2c8..95c84dab 100644
--- a/tx.c
+++ b/tx.c
@@ -76,7 +76,7 @@ mt76_tx_status_unlock(struct mt76_dev *dev, struct sk_buff_head *list)
}
}
- hw = mt76_tx_status_get_hw(dev, skb);
+ hw = mt76_tx_status_get_hw(dev, skb, wcid);
spin_lock_bh(&dev->rx_lock);
ieee80211_tx_status_ext(hw, &status);
spin_unlock_bh(&dev->rx_lock);
@@ -272,7 +272,7 @@ void __mt76_tx_complete_skb(struct mt76_dev *dev, u16 wcid_idx, struct sk_buff *
if (cb->pktid < MT_PACKET_ID_FIRST) {
struct ieee80211_rate_status rs = {};
- hw = mt76_tx_status_get_hw(dev, skb);
+ hw = mt76_tx_status_get_hw(dev, skb, wcid);
status.sta = wcid_to_sta(wcid);
if (status.sta && (wcid->rate.flags || wcid->rate.legacy)) {
rs.rate_idx = wcid->rate;
--
2.45.2