blob: d758ebcdc0a0b8babc6124ae0d878863481557f8 [file] [log] [blame]
developer1f55fcf2024-10-17 14:52:33 +08001From abadd35e16e05493cadfadde59956327312b762d Mon Sep 17 00:00:00 2001
developer66e89bc2024-04-23 14:50:01 +08002From: Shayne Chen <shayne.chen@mediatek.com>
3Date: Fri, 8 Dec 2023 18:08:13 +0800
developer1f55fcf2024-10-17 14:52:33 +08004Subject: [PATCH 093/193] mtk: mt76: mt7996: handle mapping for hw and vif
developer66e89bc2024-04-23 14:50:01 +08005
6We have several temporal workarounds for ieee80211_hw and mt76_phy
7mappings. For legacy MBSS cases, we also need a method to do the
8hw and vif mappings.
9This is a preliminary patch to add MLO support for mt7996 chipsets.
10
11Co-developed-by: Bo Jiao <Bo.Jiao@mediatek.com>
12Signed-off-by: Bo Jiao <Bo.Jiao@mediatek.com>
13Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
14---
15 dma.c | 2 +-
16 mac80211.c | 2 +-
17 mt76.h | 14 ++++++++++++--
18 mt7996/mac.c | 24 +++++++++++++++++++++++-
19 mt7996/main.c | 1 +
20 mt7996/mcu.c | 4 ++--
21 mt7996/mmio.c | 1 +
22 mt7996/mt7996.h | 3 +++
23 tx.c | 4 ++--
24 9 files changed, 46 insertions(+), 9 deletions(-)
25
26diff --git a/dma.c b/dma.c
developer1f55fcf2024-10-17 14:52:33 +080027index 38701c7..3f1fb6c 100644
developer66e89bc2024-04-23 14:50:01 +080028--- a/dma.c
29+++ b/dma.c
30@@ -685,7 +685,7 @@ free:
31
32 free_skb:
33 status.skb = tx_info.skb;
34- hw = mt76_tx_status_get_hw(dev, tx_info.skb);
35+ hw = mt76_tx_status_get_hw(dev, tx_info.skb, wcid);
36 spin_lock_bh(&dev->rx_lock);
37 ieee80211_tx_status_ext(hw, &status);
38 spin_unlock_bh(&dev->rx_lock);
39diff --git a/mac80211.c b/mac80211.c
developer1f55fcf2024-10-17 14:52:33 +080040index 0363227..b1af346 100644
developer66e89bc2024-04-23 14:50:01 +080041--- a/mac80211.c
42+++ b/mac80211.c
developerd0c89452024-10-11 16:53:27 +080043@@ -1546,7 +1546,7 @@ void mt76_wcid_cleanup(struct mt76_dev *dev, struct mt76_wcid *wcid)
developer66e89bc2024-04-23 14:50:01 +080044 spin_unlock_bh(&phy->tx_lock);
45
46 while ((skb = __skb_dequeue(&list)) != NULL) {
47- hw = mt76_tx_status_get_hw(dev, skb);
48+ hw = mt76_tx_status_get_hw(dev, skb, wcid);
49 ieee80211_free_txskb(hw, skb);
50 }
51 }
52diff --git a/mt76.h b/mt76.h
developer1f55fcf2024-10-17 14:52:33 +080053index 9fa411c..2dea07a 100644
developer66e89bc2024-04-23 14:50:01 +080054--- a/mt76.h
55+++ b/mt76.h
developerd0c89452024-10-11 16:53:27 +080056@@ -567,6 +567,9 @@ struct mt76_driver_ops {
developer66e89bc2024-04-23 14:50:01 +080057
58 void (*sta_remove)(struct mt76_dev *dev, struct ieee80211_vif *vif,
59 struct ieee80211_sta *sta);
60+
61+ void (*get_hw)(struct mt76_dev *dev, struct mt76_wcid *wcid, u8 phy_idx,
62+ struct ieee80211_hw **hw);
63 };
64
65 struct mt76_channel_state {
developerd0c89452024-10-11 16:53:27 +080066@@ -1602,14 +1605,21 @@ extern const struct nla_policy mt76_tm_policy[NUM_MT76_TM_ATTRS];
developer66e89bc2024-04-23 14:50:01 +080067
68 /* internal */
69 static inline struct ieee80211_hw *
70-mt76_tx_status_get_hw(struct mt76_dev *dev, struct sk_buff *skb)
71+mt76_tx_status_get_hw(struct mt76_dev *dev, struct sk_buff *skb,
72+ struct mt76_wcid *wcid)
73 {
74 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
75 u8 phy_idx = (info->hw_queue & MT_TX_HW_QUEUE_PHY) >> 2;
76- struct ieee80211_hw *hw = mt76_phy_hw(dev, phy_idx);
77+ struct ieee80211_hw *hw;
78
79 info->hw_queue &= ~MT_TX_HW_QUEUE_PHY;
80
81+ if (dev->drv->get_hw) {
82+ dev->drv->get_hw(dev, wcid, phy_idx, &hw);
83+ } else {
84+ hw = mt76_phy_hw(dev, phy_idx);
85+ }
86+
87 return hw;
88 }
89
90diff --git a/mt7996/mac.c b/mt7996/mac.c
developer1f55fcf2024-10-17 14:52:33 +080091index f9aa0e5..a48e4f4 100644
developer66e89bc2024-04-23 14:50:01 +080092--- a/mt7996/mac.c
93+++ b/mt7996/mac.c
developerd0c89452024-10-11 16:53:27 +080094@@ -2857,13 +2857,23 @@ static void mt7996_scan_check_sta(void *data, struct ieee80211_sta *sta)
developer66e89bc2024-04-23 14:50:01 +080095 void mt7996_scan_work(struct work_struct *work)
96 {
97 struct mt7996_phy *phy = container_of(work, struct mt7996_phy, scan_work.work);
98- struct ieee80211_hw *hw = phy->mt76->hw;
99+ struct ieee80211_vif *vif = phy->scan_vif;
100+ struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
101+ struct ieee80211_hw *hw = mvif->hw;
102 struct cfg80211_scan_request *req = phy->scan_req;
103 struct cfg80211_chan_def chandef = {};
104 int duration;
105 bool has_sta = false, active_scan = false;
106
107 mutex_lock(&phy->dev->mt76.mutex);
108+ /* don't let non-MLD AP scan other bands */
109+ if (vif->type != NL80211_IFTYPE_STATION && !ieee80211_vif_is_mld(vif) &&
110+ phy != mt7996_hw_phy(hw)) {
111+ mt7996_scan_complete(phy, false);
112+ mutex_unlock(&phy->dev->mt76.mutex);
113+ return;
114+ }
115+
116 if (phy->scan_chan_idx >= req->n_channels) {
117 mt7996_scan_complete(phy, false);
118 mutex_unlock(&phy->dev->mt76.mutex);
developerd0c89452024-10-11 16:53:27 +0800119@@ -2923,3 +2933,15 @@ void mt7996_scan_work(struct work_struct *work)
developer66e89bc2024-04-23 14:50:01 +0800120
121 ieee80211_queue_delayed_work(hw, &phy->scan_work, duration);
122 }
123+
124+void mt7996_get_hw(struct mt76_dev *dev, struct mt76_wcid *wcid, u8 phy_idx,
125+ struct ieee80211_hw **hw)
126+{
127+ struct mt7996_link_sta *mlink = wcid_to_mlink(wcid);
128+
129+ if (mlink) {
130+ *hw = mlink->sta->vif->hw;
131+ } else {
132+ *hw = mt76_phy_hw(dev, phy_idx);
133+ }
134+}
135diff --git a/mt7996/main.c b/mt7996/main.c
developer1f55fcf2024-10-17 14:52:33 +0800136index bfa78e3..02b6798 100644
developer66e89bc2024-04-23 14:50:01 +0800137--- a/mt7996/main.c
138+++ b/mt7996/main.c
139@@ -444,6 +444,7 @@ static int mt7996_add_interface(struct ieee80211_hw *hw,
140 phy->monitor_vif = vif;
141
142 mvif->dev = dev;
143+ mvif->hw = hw;
144 mvif->sta.vif = mvif;
145
146 ret = mt7996_add_bss_conf(phy, vif, &vif->bss_conf);
147diff --git a/mt7996/mcu.c b/mt7996/mcu.c
developer1f55fcf2024-10-17 14:52:33 +0800148index f4493c9..3ecaa0d 100644
developer66e89bc2024-04-23 14:50:01 +0800149--- a/mt7996/mcu.c
150+++ b/mt7996/mcu.c
developerd0c89452024-10-11 16:53:27 +0800151@@ -2955,11 +2955,11 @@ int mt7996_mcu_beacon_inband_discov(struct mt7996_dev *dev,
developer66e89bc2024-04-23 14:50:01 +0800152
153 if (changed & BSS_CHANGED_FILS_DISCOVERY) {
154 interval = conf->fils_discovery.max_interval;
155- skb = ieee80211_get_fils_discovery_tmpl(hw, vif);
156+ skb = ieee80211_get_fils_discovery_tmpl(mvif->hw, vif);
157 } else if (changed & BSS_CHANGED_UNSOL_BCAST_PROBE_RESP &&
158 conf->unsol_bcast_probe_resp_interval) {
159 interval = conf->unsol_bcast_probe_resp_interval;
160- skb = ieee80211_get_unsol_bcast_probe_resp_tmpl(hw, vif);
161+ skb = ieee80211_get_unsol_bcast_probe_resp_tmpl(mvif->hw, vif);
162 }
163
164 if (!skb) {
165diff --git a/mt7996/mmio.c b/mt7996/mmio.c
developer1f55fcf2024-10-17 14:52:33 +0800166index 8ac1b12..ee5ee5a 100644
developer66e89bc2024-04-23 14:50:01 +0800167--- a/mt7996/mmio.c
168+++ b/mt7996/mmio.c
developerd0c89452024-10-11 16:53:27 +0800169@@ -659,6 +659,7 @@ struct mt7996_dev *mt7996_mmio_probe(struct device *pdev,
developer66e89bc2024-04-23 14:50:01 +0800170 .sta_remove = mt7996_mac_sta_remove,
171 .update_survey = mt7996_update_channel,
developerd0c89452024-10-11 16:53:27 +0800172 // .set_channel = mt7996_set_channel,
developer66e89bc2024-04-23 14:50:01 +0800173+ .get_hw = mt7996_get_hw,
174 };
175 struct mt7996_dev *dev;
176 struct mt76_dev *mdev;
177diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
developer1f55fcf2024-10-17 14:52:33 +0800178index f83308d..9dd4d47 100644
developer66e89bc2024-04-23 14:50:01 +0800179--- a/mt7996/mt7996.h
180+++ b/mt7996/mt7996.h
developerd0c89452024-10-11 16:53:27 +0800181@@ -355,6 +355,7 @@ struct mt7996_vif {
developer66e89bc2024-04-23 14:50:01 +0800182
183 struct mt7996_sta sta;
184 struct mt7996_dev *dev;
185+ struct ieee80211_hw *hw;
186
187 u8 master_link_id;
188 u8 group_mld_id;
developerd0c89452024-10-11 16:53:27 +0800189@@ -905,6 +906,8 @@ int mt7996_init_tx_queues(struct mt7996_phy *phy, int idx,
developer66e89bc2024-04-23 14:50:01 +0800190 void mt7996_init_txpower(struct mt7996_phy *phy);
191 int mt7996_txbf_init(struct mt7996_dev *dev);
192 int mt7996_get_chip_sku(struct mt7996_dev *dev);
193+void mt7996_get_hw(struct mt76_dev *dev, struct mt76_wcid *wcid, u8 phy_idx,
194+ struct ieee80211_hw **hw);
195 void mt7996_reset(struct mt7996_dev *dev);
196 void mt7996_coredump(struct mt7996_dev *dev, u8 state);
197 int mt7996_run(struct ieee80211_hw *hw);
198diff --git a/tx.c b/tx.c
developer1f55fcf2024-10-17 14:52:33 +0800199index 330b8d3..7906023 100644
developer66e89bc2024-04-23 14:50:01 +0800200--- a/tx.c
201+++ b/tx.c
202@@ -76,7 +76,7 @@ mt76_tx_status_unlock(struct mt76_dev *dev, struct sk_buff_head *list)
203 }
204 }
205
206- hw = mt76_tx_status_get_hw(dev, skb);
207+ hw = mt76_tx_status_get_hw(dev, skb, wcid);
208 spin_lock_bh(&dev->rx_lock);
209 ieee80211_tx_status_ext(hw, &status);
210 spin_unlock_bh(&dev->rx_lock);
211@@ -272,7 +272,7 @@ void __mt76_tx_complete_skb(struct mt76_dev *dev, u16 wcid_idx, struct sk_buff *
212 if (cb->pktid < MT_PACKET_ID_FIRST) {
213 struct ieee80211_rate_status rs = {};
214
215- hw = mt76_tx_status_get_hw(dev, skb);
216+ hw = mt76_tx_status_get_hw(dev, skb, wcid);
217 status.sta = wcid_to_sta(wcid);
218 if (status.sta && (wcid->rate.flags || wcid->rate.legacy)) {
219 rs.rate_idx = wcid->rate;
220--
developerd0c89452024-10-11 16:53:27 +08002212.45.2
developer66e89bc2024-04-23 14:50:01 +0800222