xref: /linux/drivers/net/wireless/mediatek/mt76/scan.c (revision 91ec2035134982b98fab0609a9fd8480e8217dc1)
1 // SPDX-License-Identifier: BSD-3-Clause-Clear
2 /*
3  * Copyright (C) 2024 Felix Fietkau <nbd@nbd.name>
4  */
5 #include "mt76.h"
6 
mt76_scan_complete(struct mt76_dev * dev,bool abort)7 static void mt76_scan_complete(struct mt76_dev *dev, bool abort)
8 {
9 	struct mt76_phy *phy = dev->scan.phy;
10 	struct cfg80211_scan_info info = {
11 		.aborted = abort,
12 	};
13 
14 	lockdep_assert_held(&dev->mutex);
15 
16 	if (!phy)
17 		return;
18 
19 	clear_bit(MT76_SCANNING, &phy->state);
20 
21 	/* Re-program the operating channel even when the scan never left it:
22 	 * any channel set during the scan ran with MT76_SCANNING held, which
23 	 * left DFS radar detection disabled
24 	 */
25 	if (phy->main_chandef.chan &&
26 	    !test_bit(MT76_MCU_RESET, &dev->phy.state)) {
27 		bool offchannel = phy->offchannel;
28 
29 		__mt76_set_channel(phy, &phy->main_chandef, false);
30 		if (offchannel)
31 			mt76_offchannel_notify(phy, false);
32 	}
33 	mt76_put_vif_phy_link(phy, dev->scan.vif, dev->scan.mlink);
34 	memset(&dev->scan, 0, sizeof(dev->scan));
35 	if (!test_bit(MT76_MCU_RESET, &dev->phy.state))
36 		ieee80211_scan_completed(phy->hw, &info);
37 }
38 
mt76_abort_scan(struct mt76_dev * dev)39 void mt76_abort_scan(struct mt76_dev *dev)
40 {
41 	spin_lock_bh(&dev->scan_lock);
42 	dev->scan.beacon_wait = false;
43 	spin_unlock_bh(&dev->scan_lock);
44 
45 	cancel_delayed_work_sync(&dev->scan_work);
46 
47 	mutex_lock(&dev->mutex);
48 	mt76_scan_complete(dev, true);
49 	mutex_unlock(&dev->mutex);
50 }
51 EXPORT_SYMBOL_GPL(mt76_abort_scan);
52 
53 static void
mt76_scan_send_probe(struct mt76_dev * dev,struct cfg80211_ssid * ssid)54 mt76_scan_send_probe(struct mt76_dev *dev, struct cfg80211_ssid *ssid)
55 {
56 	struct cfg80211_scan_request *req = dev->scan.req;
57 	struct ieee80211_vif *vif = dev->scan.vif;
58 	struct mt76_vif_link *mvif = dev->scan.mlink;
59 	enum nl80211_band band = dev->scan.chan->band;
60 	struct mt76_phy *phy = dev->scan.phy;
61 	struct ieee80211_tx_info *info;
62 	struct sk_buff *skb;
63 	u8 link_id;
64 
65 	skb = ieee80211_probereq_get(phy->hw, vif->addr, ssid->ssid,
66 				     ssid->ssid_len, req->ie_len);
67 	if (!skb)
68 		return;
69 
70 	if (is_unicast_ether_addr(req->bssid)) {
71 		struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
72 
73 		ether_addr_copy(hdr->addr1, req->bssid);
74 		ether_addr_copy(hdr->addr3, req->bssid);
75 	}
76 
77 	if (req->ie_len)
78 		skb_put_data(skb, req->ie, req->ie_len);
79 
80 	skb->priority = 7;
81 	skb_set_queue_mapping(skb, IEEE80211_AC_VO);
82 
83 	rcu_read_lock();
84 
85 	if (!ieee80211_tx_prepare_skb(phy->hw, vif, skb, band, NULL))
86 		goto out;
87 
88 	info = IEEE80211_SKB_CB(skb);
89 	if (req->no_cck)
90 		info->flags |= IEEE80211_TX_CTL_NO_CCK_RATE;
91 	info->control.flags |= IEEE80211_TX_CTRL_DONT_USE_RATE_MASK;
92 
93 	link_id = mvif->wcid ? mvif->wcid->link_id : IEEE80211_LINK_UNSPECIFIED;
94 	info->control.flags &= ~IEEE80211_TX_CTRL_MLO_LINK;
95 	info->control.flags |= u32_encode_bits(link_id, IEEE80211_TX_CTRL_MLO_LINK);
96 
97 	mt76_tx(phy, NULL, mvif->wcid, skb);
98 
99 out:
100 	rcu_read_unlock();
101 }
102 
mt76_scan_rx_beacon(struct mt76_dev * dev,struct ieee80211_channel * chan)103 void mt76_scan_rx_beacon(struct mt76_dev *dev, struct ieee80211_channel *chan)
104 {
105 	struct mt76_phy *phy;
106 
107 	spin_lock(&dev->scan_lock);
108 
109 	if (!dev->scan.beacon_wait || dev->scan.beacon_received ||
110 	    dev->scan.chan != chan)
111 		goto out;
112 
113 	phy = dev->scan.phy;
114 	if (!phy)
115 		goto out;
116 
117 	dev->scan.beacon_received = true;
118 	ieee80211_queue_delayed_work(phy->hw, &dev->scan_work, 0);
119 
120 out:
121 	spin_unlock(&dev->scan_lock);
122 }
123 
mt76_scan_work(struct work_struct * work)124 void mt76_scan_work(struct work_struct *work)
125 {
126 	struct mt76_dev *dev = container_of(work, struct mt76_dev,
127 					    scan_work.work);
128 	struct cfg80211_scan_request *req = dev->scan.req;
129 	struct cfg80211_chan_def chandef = {};
130 	struct mt76_phy *phy = dev->scan.phy;
131 	int duration = HZ / 9; /* ~110 ms */
132 	bool beacon_rx, offchannel = true;
133 	int i;
134 
135 	if (!phy || !req)
136 		return;
137 
138 	spin_lock_bh(&dev->scan_lock);
139 	beacon_rx = dev->scan.beacon_wait && dev->scan.beacon_received;
140 	dev->scan.beacon_wait = false;
141 	spin_unlock_bh(&dev->scan_lock);
142 
143 	if (beacon_rx)
144 		goto probe;
145 
146 	if (dev->scan.chan_idx >= req->n_channels) {
147 		mutex_lock(&dev->mutex);
148 		mt76_scan_complete(dev, false);
149 		mutex_unlock(&dev->mutex);
150 		return;
151 	}
152 
153 	if (dev->scan.chan && phy->num_sta && phy->offchannel) {
154 		dev->scan.chan = NULL;
155 		mt76_set_channel(phy, &phy->main_chandef, false);
156 		mt76_offchannel_notify(phy, false);
157 		goto out;
158 	}
159 
160 	dev->scan.chan = req->channels[dev->scan.chan_idx++];
161 	offchannel = mt76_offchannel_chandef(phy, dev->scan.chan, &chandef);
162 
163 	if (offchannel)
164 		mt76_offchannel_notify(phy, true);
165 	mt76_set_channel(phy, &chandef, offchannel);
166 
167 	if (!req->n_ssids)
168 		goto out;
169 
170 	if (chandef.chan->flags & (IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_RADAR)) {
171 		spin_lock_bh(&dev->scan_lock);
172 		dev->scan.beacon_received = false;
173 		dev->scan.beacon_wait = true;
174 		spin_unlock_bh(&dev->scan_lock);
175 		goto out;
176 	}
177 
178 probe:
179 	if (phy->offchannel)
180 		duration = HZ / 16; /* ~60 ms */
181 	local_bh_disable();
182 	for (i = 0; i < req->n_ssids; i++)
183 		mt76_scan_send_probe(dev, &req->ssids[i]);
184 	local_bh_enable();
185 
186 out:
187 	if (dev->scan.chan && phy->offchannel)
188 		duration = max_t(int, duration,
189 			         msecs_to_jiffies(req->duration +
190 						  (req->duration >> 5)));
191 
192 	ieee80211_queue_delayed_work(dev->phy.hw, &dev->scan_work, duration);
193 }
194 
mt76_hw_scan(struct ieee80211_hw * hw,struct ieee80211_vif * vif,struct ieee80211_scan_request * req)195 int mt76_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
196 		 struct ieee80211_scan_request *req)
197 {
198 	struct mt76_phy *phy = hw->priv;
199 	struct mt76_dev *dev = phy->dev;
200 	struct mt76_vif_link *mlink;
201 	int ret = 0;
202 
203 	if (hw->wiphy->n_radio > 1) {
204 		phy = dev->band_phys[req->req.channels[0]->band];
205 		if (!phy)
206 			return -EINVAL;
207 	}
208 
209 	mutex_lock(&dev->mutex);
210 
211 	if (dev->scan.req || phy->roc_vif ||
212 	    test_bit(MT76_MCU_RESET, &dev->phy.state)) {
213 		ret = -EBUSY;
214 		goto out;
215 	}
216 
217 	mlink = mt76_get_vif_phy_link(phy, vif);
218 	if (IS_ERR(mlink)) {
219 		ret = PTR_ERR(mlink);
220 		goto out;
221 	}
222 
223 	memset(&dev->scan, 0, sizeof(dev->scan));
224 	dev->scan.req = &req->req;
225 	dev->scan.vif = vif;
226 	dev->scan.phy = phy;
227 	dev->scan.mlink = mlink;
228 	set_bit(MT76_SCANNING, &phy->state);
229 	ieee80211_queue_delayed_work(dev->phy.hw, &dev->scan_work, 0);
230 
231 out:
232 	mutex_unlock(&dev->mutex);
233 
234 	return ret;
235 }
236 EXPORT_SYMBOL_GPL(mt76_hw_scan);
237 
mt76_cancel_hw_scan(struct ieee80211_hw * hw,struct ieee80211_vif * vif)238 void mt76_cancel_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
239 {
240 	struct mt76_phy *phy = hw->priv;
241 
242 	mt76_abort_scan(phy->dev);
243 }
244 EXPORT_SYMBOL_GPL(mt76_cancel_hw_scan);
245