blob: 4aba3ff87685cb7fbc3902ce910bf4fa3e98c7f2 [file] [log] [blame]
developer617abbd2024-04-23 14:50:01 +08001From f60e775a0f4ca3389d4777b1b2200a5be06cab92 Mon Sep 17 00:00:00 2001
2From: Shayne Chen <shayne.chen@mediatek.com>
3Date: Wed, 13 Dec 2023 16:58:31 +0800
4Subject: [PATCH 102/116] wifi: mt76: mt7996: rework scanning parts for MLD STA
5 support
6
7During the first scanning, the STA VIF is still a legacy interface,
8and at the moment it doesn't know if it's MLD or not. So do dome tricks
9here to let the legacy interface be abled to scan all bands.
10This is a preliminary patch to add MLO support for mt7996 chipsets.
11
12Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
13---
14 mt7996/mac.c | 34 +++++++++++++++++++++++++---------
15 mt7996/main.c | 17 +++++++++++++++++
16 2 files changed, 42 insertions(+), 9 deletions(-)
17
18diff --git a/mt7996/mac.c b/mt7996/mac.c
19index 6ca3e06e2..d6d1c0798 100644
20--- a/mt7996/mac.c
21+++ b/mt7996/mac.c
22@@ -2770,23 +2770,40 @@ static void
23 mt7996_scan_send_probe(struct mt7996_phy *phy, struct cfg80211_ssid *ssid,
24 const u8 *dst)
25 {
26- struct ieee80211_hw *hw = phy->mt76->hw;
27 struct cfg80211_scan_request *req = phy->scan_req;
28 struct ieee80211_vif *vif = phy->scan_vif;
29+ struct ieee80211_bss_conf *conf;
30 struct mt7996_vif *mvif;
31 struct mt7996_link_sta *mlink;
32 struct ieee80211_tx_info *info;
33+ struct ieee80211_hw *hw;
34 struct sk_buff *skb;
35+ unsigned long valid_links;
36+ unsigned int link_id;
37
38 if (!req || !vif)
39 return;
40
41+ valid_links = vif->valid_links ?: BIT(0);
42 mvif = (struct mt7996_vif *)vif->drv_priv;
43+ hw = mvif->hw;
44+
45+ rcu_read_lock();
46+
47+ for_each_set_bit(link_id, &valid_links, IEEE80211_MLD_MAX_NUM_LINKS) {
48+ conf = rcu_dereference(vif->link_conf[link_id]);
49+ mlink = rcu_dereference(mvif->sta.link[link_id]);
50+ if (mlink->wcid.phy_idx != phy->mt76->band_idx)
51+ continue;
52+ }
53
54- skb = ieee80211_probereq_get(hw, vif->addr,
55+ if (unlikely(!conf))
56+ goto unlock;
57+
58+ skb = ieee80211_probereq_get(hw, conf->addr,
59 ssid->ssid, ssid->ssid_len, req->ie_len);
60 if (!skb)
61- return;
62+ goto unlock;
63
64 if (is_unicast_ether_addr(dst)) {
65 struct ieee80211_hdr_3addr *hdr =
66@@ -2804,30 +2821,29 @@ mt7996_scan_send_probe(struct mt7996_phy *phy, struct cfg80211_ssid *ssid,
67
68 skb_set_queue_mapping(skb, IEEE80211_AC_VO);
69
70- rcu_read_lock();
71- if (!ieee80211_tx_prepare_skb(mt76_main_hw(phy->mt76), vif, skb,
72- phy->scan_chan->band,
73- NULL)) {
74+ if (!ieee80211_tx_prepare_skb(hw, vif, skb,
75+ phy->scan_chan->band, NULL)) {
76 rcu_read_unlock();
77 ieee80211_free_txskb(hw, skb);
78 return;
79 }
80
81 local_bh_disable();
82- mlink = rcu_dereference(mvif->sta.link[0]);
83 mt76_tx(phy->mt76, NULL, &mlink->wcid, skb);
84 local_bh_enable();
85
86+unlock:
87 rcu_read_unlock();
88 }
89
90 void mt7996_scan_complete(struct mt7996_phy *phy, bool aborted)
91 {
92+ struct mt7996_vif *mvif = (struct mt7996_vif *)phy->scan_vif->drv_priv;
93 struct cfg80211_scan_info info = {
94 .aborted = aborted,
95 };
96
97- ieee80211_scan_completed(phy->mt76->hw, &info);
98+ ieee80211_scan_completed(mvif->hw, &info);
99 phy->scan_chan = NULL;
100 phy->scan_req = NULL;
101 phy->scan_vif = NULL;
102diff --git a/mt7996/main.c b/mt7996/main.c
103index 8bf520120..66972080f 100644
104--- a/mt7996/main.c
105+++ b/mt7996/main.c
106@@ -2191,6 +2191,8 @@ mt7996_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
107 {
108 struct cfg80211_scan_request *req = &hw_req->req;
109 struct mt7996_phy *phy = mt7996_band_phy(hw, req->channels[0]->band);
110+ struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
111+ int ret;
112
113 mutex_lock(&phy->dev->mt76.mutex);
114 if (WARN_ON(phy->scan_req || phy->scan_chan)) {
115@@ -2202,6 +2204,17 @@ mt7996_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
116 phy->scan_req = req;
117 phy->scan_vif = vif;
118 phy->scan_chan_idx = 0;
119+ if (vif->type == NL80211_IFTYPE_STATION && !ieee80211_vif_is_mld(vif) &&
120+ (phy->mt76 != mvif->deflink.phy->mt76)) {
121+ phy->mt76->main_phy = hw->priv;
122+ mt7996_remove_bss_conf(vif, &vif->bss_conf, &mvif->deflink);
123+
124+ ret = mt7996_add_bss_conf(phy, vif, &vif->bss_conf);
125+ if (ret) {
126+ mutex_unlock(&phy->dev->mt76.mutex);
127+ return ret;
128+ }
129+ }
130 mutex_unlock(&phy->dev->mt76.mutex);
131
132 ieee80211_queue_delayed_work(mt76_main_hw(phy->mt76), &phy->scan_work, 0);
133@@ -2212,6 +2225,7 @@ mt7996_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
134 static void
135 mt7996_cancel_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
136 {
137+ struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
138 int band;
139
140 for (band = 0; band < NUM_NL80211_BANDS; band++) {
141@@ -2229,6 +2243,9 @@ mt7996_cancel_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
142
143 mutex_lock(&phy->dev->mt76.mutex);
144 mt7996_scan_complete(phy, true);
145+ if (vif->type == NL80211_IFTYPE_STATION && !ieee80211_vif_is_mld(vif) &&
146+ (phy->mt76 != mvif->deflink.phy->mt76))
147+ phy->mt76->main_phy = NULL;
148 mutex_unlock(&phy->dev->mt76.mutex);
149 }
150 }
151--
1522.39.2
153