blob: 9977a88042927e8018f2e52ab7539bbcfa75d22a [file] [log] [blame]
developerd0c89452024-10-11 16:53:27 +08001From 953012de13153dbc078b6fe3cc64d6d44e2d251f Mon Sep 17 00:00:00 2001
developer66e89bc2024-04-23 14:50:01 +08002From: Shayne Chen <shayne.chen@mediatek.com>
3Date: Fri, 3 Nov 2023 21:44:45 +0800
developerd0c89452024-10-11 16:53:27 +08004Subject: [PATCH 075/223] mtk: mt76: mt7996: implement and switch to hw scan
developer66e89bc2024-04-23 14:50:01 +08005 callbacks
6
7To support MLO, hw_scan callbacks are mandatory. However, the
8firmware of AP-segment doesn't support hw_scan commands, so we need
9to implement it in the driver.
10This is a preliminary patch to add MLO support for mt7996 chipsets.
11
12If the cfg80211_scan_request contains an unicast BSSID, the probe
13request should be unicast.
14This works for ML probe request, which should be unicast.
15
developerd0c89452024-10-11 16:53:27 +080016Change-Id: Ic096b10e4a82211be4c5c435d3e34e0a76ea3b9e
developer66e89bc2024-04-23 14:50:01 +080017Co-developed-by: Michael-CY Lee <michael-cy.lee@mediatek.com>
18Signed-off-by: Michael-CY Lee <michael-cy.lee@mediatek.com>
developer05f3b2b2024-08-19 19:17:34 +080019Co-developed-by: Peter Chiu <chui-hao.chiu@mediatek.com>
20Signed-off-by: Peter Chiu <chui-hao.chiu@mediatek.com>
developer66e89bc2024-04-23 14:50:01 +080021Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
22---
23 mac80211.c | 3 +-
24 mt76.h | 2 +
25 mt7996/init.c | 5 ++
26 mt7996/mac.c | 141 ++++++++++++++++++++++++++++++++++++++++++++++++
developerd0c89452024-10-11 16:53:27 +080027 mt7996/main.c | 100 +++++++++++++++++++++++++++++++---
developer66e89bc2024-04-23 14:50:01 +080028 mt7996/mcu.c | 3 +-
developerd0c89452024-10-11 16:53:27 +080029 mt7996/mmio.c | 2 +-
developer66e89bc2024-04-23 14:50:01 +080030 mt7996/mt7996.h | 11 +++-
developerd0c89452024-10-11 16:53:27 +080031 8 files changed, 256 insertions(+), 11 deletions(-)
developer66e89bc2024-04-23 14:50:01 +080032
33diff --git a/mac80211.c b/mac80211.c
developerd0c89452024-10-11 16:53:27 +080034index b08a9388..cad85f19 100644
developer66e89bc2024-04-23 14:50:01 +080035--- a/mac80211.c
36+++ b/mac80211.c
developer05f3b2b2024-08-19 19:17:34 +080037@@ -820,7 +820,7 @@ bool mt76_has_tx_pending(struct mt76_phy *phy)
developer66e89bc2024-04-23 14:50:01 +080038 }
39 EXPORT_SYMBOL_GPL(mt76_has_tx_pending);
40
41-static struct mt76_channel_state *
42+struct mt76_channel_state *
43 mt76_channel_state(struct mt76_phy *phy, struct ieee80211_channel *c)
44 {
45 struct mt76_sband *msband;
developer05f3b2b2024-08-19 19:17:34 +080046@@ -836,6 +836,7 @@ mt76_channel_state(struct mt76_phy *phy, struct ieee80211_channel *c)
developer66e89bc2024-04-23 14:50:01 +080047 idx = c - &msband->sband.channels[0];
48 return &msband->chan[idx];
49 }
50+EXPORT_SYMBOL_GPL(mt76_channel_state);
51
52 void mt76_update_survey_active_time(struct mt76_phy *phy, ktime_t time)
53 {
54diff --git a/mt76.h b/mt76.h
developerd0c89452024-10-11 16:53:27 +080055index aad7f557..36e92dfe 100644
developer66e89bc2024-04-23 14:50:01 +080056--- a/mt76.h
57+++ b/mt76.h
developerd0c89452024-10-11 16:53:27 +080058@@ -1483,6 +1483,8 @@ void mt76_release_buffered_frames(struct ieee80211_hw *hw,
developer66e89bc2024-04-23 14:50:01 +080059 bool more_data);
60 bool mt76_has_tx_pending(struct mt76_phy *phy);
developerd0c89452024-10-11 16:53:27 +080061 int mt76_update_channel(struct mt76_phy *phy);
developer66e89bc2024-04-23 14:50:01 +080062+struct mt76_channel_state *
63+mt76_channel_state(struct mt76_phy *phy, struct ieee80211_channel *c);
developer66e89bc2024-04-23 14:50:01 +080064 void mt76_update_survey(struct mt76_phy *phy);
65 void mt76_update_survey_active_time(struct mt76_phy *phy, ktime_t time);
developerd0c89452024-10-11 16:53:27 +080066 int mt76_get_survey(struct ieee80211_hw *hw, int idx,
developer66e89bc2024-04-23 14:50:01 +080067diff --git a/mt7996/init.c b/mt7996/init.c
developerd0c89452024-10-11 16:53:27 +080068index 48798711..a188fa1d 100644
developer66e89bc2024-04-23 14:50:01 +080069--- a/mt7996/init.c
70+++ b/mt7996/init.c
developer05f3b2b2024-08-19 19:17:34 +080071@@ -459,6 +459,9 @@ mt7996_init_wiphy(struct ieee80211_hw *hw, struct mtk_wed_device *wed)
developer66e89bc2024-04-23 14:50:01 +080072
73 wiphy->available_antennas_rx = phy->mt76->antenna_mask;
74 wiphy->available_antennas_tx = phy->mt76->antenna_mask;
75+
76+ wiphy->max_scan_ssids = 4;
77+ wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN;
78 }
79
80 static void
developer05f3b2b2024-08-19 19:17:34 +080081@@ -679,6 +682,7 @@ static int mt7996_register_phy(struct mt7996_dev *dev, struct mt7996_phy *phy,
developer66e89bc2024-04-23 14:50:01 +080082 mphy->dev->phys[band] = mphy;
83
84 INIT_DELAYED_WORK(&mphy->mac_work, mt7996_mac_work);
85+ INIT_DELAYED_WORK(&phy->scan_work, mt7996_scan_work);
86
87 ret = mt7996_eeprom_parse_hw_cap(dev, phy);
88 if (ret)
developerd0c89452024-10-11 16:53:27 +080089@@ -1594,6 +1598,7 @@ int mt7996_register_device(struct mt7996_dev *dev)
developer66e89bc2024-04-23 14:50:01 +080090 dev->mt76.phy.priv = &dev->phy;
91 INIT_WORK(&dev->rc_work, mt7996_mac_sta_rc_work);
92 INIT_DELAYED_WORK(&dev->mphy.mac_work, mt7996_mac_work);
93+ INIT_DELAYED_WORK(&dev->phy.scan_work, mt7996_scan_work);
94 INIT_DELAYED_WORK(&dev->scs_work, mt7996_mcu_scs_sta_poll);
95 INIT_LIST_HEAD(&dev->sta_rc_list);
96 INIT_LIST_HEAD(&dev->twt_list);
97diff --git a/mt7996/mac.c b/mt7996/mac.c
developerd0c89452024-10-11 16:53:27 +080098index 4ea44f8d..5c29fe7f 100644
developer66e89bc2024-04-23 14:50:01 +080099--- a/mt7996/mac.c
100+++ b/mt7996/mac.c
developerd0c89452024-10-11 16:53:27 +0800101@@ -2705,3 +2705,144 @@ void mt7996_mac_twt_teardown_flow(struct mt7996_dev *dev,
developer66e89bc2024-04-23 14:50:01 +0800102 dev->twt.table_mask &= ~BIT(flow->table_id);
103 dev->twt.n_agrt--;
104 }
105+
106+static void
107+mt7996_scan_send_probe(struct mt7996_phy *phy, struct cfg80211_ssid *ssid,
108+ const u8 *dst)
109+{
110+ struct ieee80211_hw *hw = phy->mt76->hw;
111+ struct cfg80211_scan_request *req = phy->scan_req;
112+ struct ieee80211_vif *vif = phy->scan_vif;
113+ struct mt7996_vif *mvif;
114+ struct mt76_wcid *wcid;
115+ struct ieee80211_tx_info *info;
116+ struct sk_buff *skb;
117+
118+ if (!req || !vif)
119+ return;
120+
121+ mvif = (struct mt7996_vif *)vif->drv_priv;
122+ wcid = &mvif->sta.wcid;
123+
124+ skb = ieee80211_probereq_get(hw, vif->addr,
125+ ssid->ssid, ssid->ssid_len, req->ie_len);
126+ if (!skb)
127+ return;
128+
129+ if (is_unicast_ether_addr(dst)) {
130+ struct ieee80211_hdr_3addr *hdr =
131+ (struct ieee80211_hdr_3addr *)skb->data;
132+ memcpy(hdr->addr1, dst, ETH_ALEN);
133+ memcpy(hdr->addr3, dst, ETH_ALEN);
134+ }
135+
136+ info = IEEE80211_SKB_CB(skb);
137+ if (req->no_cck)
138+ info->flags |= IEEE80211_TX_CTL_NO_CCK_RATE;
139+
140+ if (req->ie_len)
141+ skb_put_data(skb, req->ie, req->ie_len);
142+
143+ skb_set_queue_mapping(skb, IEEE80211_AC_VO);
144+
145+ rcu_read_lock();
146+ if (!ieee80211_tx_prepare_skb(hw, vif, skb,
147+ phy->scan_chan->band,
148+ NULL)) {
149+ rcu_read_unlock();
150+ ieee80211_free_txskb(hw, skb);
151+ return;
152+ }
153+
154+ local_bh_disable();
155+ mt76_tx(phy->mt76, NULL, wcid, skb);
156+ local_bh_enable();
157+
158+ rcu_read_unlock();
159+}
160+
161+void mt7996_scan_complete(struct mt7996_phy *phy, bool aborted)
162+{
163+ struct cfg80211_scan_info info = {
164+ .aborted = aborted,
165+ };
166+
167+ ieee80211_scan_completed(phy->mt76->hw, &info);
168+ phy->scan_chan = NULL;
169+ phy->scan_req = NULL;
170+ phy->scan_vif = NULL;
171+ clear_bit(MT76_SCANNING, &phy->mt76->state);
172+}
173+
174+static void mt7996_scan_check_sta(void *data, struct ieee80211_sta *sta)
175+{
176+ bool *has_sta = data;
177+
178+ if (*has_sta)
179+ return;
180+ *has_sta = true;
181+}
182+
183+void mt7996_scan_work(struct work_struct *work)
184+{
185+ struct mt7996_phy *phy = container_of(work, struct mt7996_phy, scan_work.work);
186+ struct ieee80211_hw *hw = phy->mt76->hw;
187+ struct cfg80211_scan_request *req = phy->scan_req;
188+ struct cfg80211_chan_def chandef = {};
189+ int duration;
190+ bool has_sta = false, active_scan = false;
191+
192+ mutex_lock(&phy->dev->mt76.mutex);
193+ if (phy->scan_chan_idx >= req->n_channels) {
194+ mt7996_scan_complete(phy, false);
195+ mutex_unlock(&phy->dev->mt76.mutex);
196+
197+ mt7996_set_channel(phy, &hw->conf.chandef);
198+
199+ return;
200+ }
201+
202+ ieee80211_iterate_stations_atomic(hw, mt7996_scan_check_sta, &has_sta);
203+
204+ /* go back to operating channel */
205+ if (has_sta && phy->scan_chan) {
206+ phy->scan_chan = NULL;
207+ mutex_unlock(&phy->dev->mt76.mutex);
208+
209+ mt7996_set_channel(phy, &phy->mt76->chandef);
210+
211+ ieee80211_queue_delayed_work(hw, &phy->scan_work, HZ / 10);
212+
213+ return;
214+ }
215+
216+ wiphy_info(hw->wiphy, "hw scan %d MHz\n",
217+ req->channels[phy->scan_chan_idx]->center_freq);
218+
219+ phy->scan_chan = req->channels[phy->scan_chan_idx++];
220+
221+ if (!req->n_ssids ||
222+ (phy->scan_chan->flags & (IEEE80211_CHAN_NO_IR |
223+ IEEE80211_CHAN_RADAR))) {
224+ duration = HZ / 9; /* ~110 ms */
225+ } else {
226+ duration = HZ / 16; /* ~60 ms */
227+ active_scan = true;
228+ }
229+
230+ cfg80211_chandef_create(&chandef, phy->scan_chan, NL80211_CHAN_HT20);
231+ mutex_unlock(&phy->dev->mt76.mutex);
232+
233+ mt7996_set_channel(phy, &chandef);
234+
235+ if (active_scan) {
236+ int i;
237+
238+ mutex_lock(&phy->dev->mt76.mutex);
239+ for (i = 0; i < req->n_ssids; i++)
240+ mt7996_scan_send_probe(phy, &req->ssids[i], req->bssid);
241+ mutex_unlock(&phy->dev->mt76.mutex);
242+ }
243+
244+ ieee80211_queue_delayed_work(hw, &phy->scan_work, duration);
245+}
246diff --git a/mt7996/main.c b/mt7996/main.c
developerd0c89452024-10-11 16:53:27 +0800247index 3a274ba7..475763e4 100644
developer66e89bc2024-04-23 14:50:01 +0800248--- a/mt7996/main.c
249+++ b/mt7996/main.c
250@@ -312,6 +312,8 @@ static void mt7996_remove_interface(struct ieee80211_hw *hw,
251 struct mt7996_phy *phy = mt7996_hw_phy(hw);
252 int idx = msta->wcid.idx;
253
254+ cancel_delayed_work_sync(&phy->scan_work);
255+
256 mt7996_mcu_add_sta(dev, vif, NULL, false, false);
257 mt7996_mcu_add_bss_info(phy, vif, false);
258
259@@ -323,6 +325,10 @@ static void mt7996_remove_interface(struct ieee80211_hw *hw,
260 rcu_assign_pointer(dev->mt76.wcid[idx], NULL);
261
262 mutex_lock(&dev->mt76.mutex);
263+
264+ if (test_bit(MT76_SCANNING, &phy->mt76->state))
265+ mt7996_scan_complete(phy, true);
266+
267 dev->mt76.vif_mask &= ~BIT_ULL(mvif->mt76.idx);
268 phy->omac_mask &= ~BIT_ULL(mvif->mt76.omac_idx);
269 mutex_unlock(&dev->mt76.mutex);
developerd0c89452024-10-11 16:53:27 +0800270@@ -335,11 +341,44 @@ static void mt7996_remove_interface(struct ieee80211_hw *hw,
developer66e89bc2024-04-23 14:50:01 +0800271 mt76_wcid_cleanup(&dev->mt76, &msta->wcid);
272 }
273
developerd0c89452024-10-11 16:53:27 +0800274-int mt7996_set_channel(struct mt76_phy *mphy)
developer66e89bc2024-04-23 14:50:01 +0800275+static void ___mt7996_set_channel(struct mt7996_phy *phy,
276+ struct cfg80211_chan_def *chandef)
developerd0c89452024-10-11 16:53:27 +0800277 {
278- struct mt7996_phy *phy = mphy->priv;
developer66e89bc2024-04-23 14:50:01 +0800279+ struct mt76_dev *mdev = phy->mt76->dev;
280+ struct mt76_phy *mphy = phy->mt76;
281+ bool offchannel = phy->scan_chan != NULL;
282+ int timeout = HZ / 5;
283+
284+ wait_event_timeout(mdev->tx_wait, !mt76_has_tx_pending(mphy), timeout);
285+ mt76_update_survey(mphy);
286+
287+ if (mphy->chandef.chan->center_freq != chandef->chan->center_freq ||
288+ mphy->chandef.width != chandef->width)
289+ mphy->dfs_state = MT_DFS_STATE_UNKNOWN;
290+
291+ mphy->chandef = *chandef;
292+ mphy->chan_state = mt76_channel_state(mphy, chandef->chan);
293+
294+ if (!offchannel)
295+ mphy->main_chan = chandef->chan;
296+
297+ if (chandef->chan != mphy->main_chan)
298+ memset(mphy->chan_state, 0, sizeof(*mphy->chan_state));
299+}
300+
301+static int __mt7996_set_channel(struct mt7996_phy *phy,
302+ struct cfg80211_chan_def *chandef)
developerd0c89452024-10-11 16:53:27 +0800303+{
304+ struct mt7996_dev *dev = phy->dev;
developer66e89bc2024-04-23 14:50:01 +0800305 int ret;
developer66e89bc2024-04-23 14:50:01 +0800306
developerd0c89452024-10-11 16:53:27 +0800307+ cancel_delayed_work_sync(&phy->mt76->mac_work);
308+
309+ mutex_lock(&dev->mt76.mutex);
310+ set_bit(MT76_RESET, &phy->mt76->state);
311+
developer66e89bc2024-04-23 14:50:01 +0800312+ ___mt7996_set_channel(phy, chandef);
developerd0c89452024-10-11 16:53:27 +0800313+
developer66e89bc2024-04-23 14:50:01 +0800314 if (dev->cal) {
315 ret = mt7996_mcu_apply_tx_dpd(phy);
developerd0c89452024-10-11 16:53:27 +0800316 if (ret)
317@@ -372,6 +411,19 @@ out:
developer66e89bc2024-04-23 14:50:01 +0800318 return ret;
319 }
320
321+int mt7996_set_channel(struct mt7996_phy *phy, struct cfg80211_chan_def *chandef)
322+{
323+ int ret;
324+
325+ ieee80211_stop_queues(phy->mt76->hw);
326+ ret = __mt7996_set_channel(phy, chandef);
327+ if (ret)
328+ return ret;
329+ ieee80211_wake_queues(phy->mt76->hw);
330+
331+ return 0;
332+}
333+
334 static int mt7996_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
335 struct ieee80211_vif *vif, struct ieee80211_sta *sta,
336 struct ieee80211_key_conf *key)
developerd0c89452024-10-11 16:53:27 +0800337@@ -468,9 +520,7 @@ static int mt7996_config(struct ieee80211_hw *hw, u32 changed)
developer66e89bc2024-04-23 14:50:01 +0800338 if (ret)
339 return ret;
340
developerd0c89452024-10-11 16:53:27 +0800341- ret = mt76_update_channel(phy->mt76);
developer66e89bc2024-04-23 14:50:01 +0800342- if (ret)
343- return ret;
developer66e89bc2024-04-23 14:50:01 +0800344+ mt7996_set_channel(phy, &hw->conf.chandef);
345 }
346
347 if (changed & (IEEE80211_CONF_CHANGE_POWER |
developerd0c89452024-10-11 16:53:27 +0800348@@ -1637,6 +1687,42 @@ mt7996_net_fill_forward_path(struct ieee80211_hw *hw,
developer66e89bc2024-04-23 14:50:01 +0800349
350 #endif
351
352+static int
353+mt7996_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
354+ struct ieee80211_scan_request *hw_req)
355+{
356+ struct cfg80211_scan_request *req = &hw_req->req;
357+ struct mt7996_phy *phy = mt7996_hw_phy(hw);
358+
359+ mutex_lock(&phy->dev->mt76.mutex);
360+ if (WARN_ON(phy->scan_req || phy->scan_chan)) {
361+ mutex_unlock(&phy->dev->mt76.mutex);
362+ return -EBUSY;
363+ }
364+
365+ set_bit(MT76_SCANNING, &phy->mt76->state);
366+ phy->scan_req = req;
367+ phy->scan_vif = vif;
368+ phy->scan_chan_idx = 0;
369+ mutex_unlock(&phy->dev->mt76.mutex);
370+
371+ ieee80211_queue_delayed_work(hw, &phy->scan_work, 0);
372+
373+ return 0;
374+}
375+
376+static void
377+mt7996_cancel_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
378+{
379+ struct mt7996_phy *phy = mt7996_hw_phy(hw);
380+
381+ cancel_delayed_work_sync(&phy->scan_work);
382+
383+ mutex_lock(&phy->dev->mt76.mutex);
384+ mt7996_scan_complete(phy, true);
385+ mutex_unlock(&phy->dev->mt76.mutex);
386+}
387+
388 const struct ieee80211_ops mt7996_ops = {
developer05f3b2b2024-08-19 19:17:34 +0800389 .add_chanctx = ieee80211_emulate_add_chanctx,
390 .remove_chanctx = ieee80211_emulate_remove_chanctx,
developerd0c89452024-10-11 16:53:27 +0800391@@ -1659,8 +1745,8 @@ const struct ieee80211_ops mt7996_ops = {
developer66e89bc2024-04-23 14:50:01 +0800392 .ampdu_action = mt7996_ampdu_action,
393 .set_rts_threshold = mt7996_set_rts_threshold,
394 .wake_tx_queue = mt76_wake_tx_queue,
395- .sw_scan_start = mt76_sw_scan,
396- .sw_scan_complete = mt76_sw_scan_complete,
397+ .hw_scan = mt7996_hw_scan,
398+ .cancel_hw_scan = mt7996_cancel_hw_scan,
399 .release_buffered_frames = mt76_release_buffered_frames,
400 .get_txpower = mt76_get_txpower,
401 .channel_switch_beacon = mt7996_channel_switch_beacon,
402diff --git a/mt7996/mcu.c b/mt7996/mcu.c
developerd0c89452024-10-11 16:53:27 +0800403index d559df86..746fc223 100644
developer66e89bc2024-04-23 14:50:01 +0800404--- a/mt7996/mcu.c
405+++ b/mt7996/mcu.c
developerd0c89452024-10-11 16:53:27 +0800406@@ -3786,7 +3786,8 @@ int mt7996_mcu_set_chan_info(struct mt7996_phy *phy, u16 tag)
developer66e89bc2024-04-23 14:50:01 +0800407 if (phy->mt76->hw->conf.flags & IEEE80211_CONF_MONITOR)
408 req.switch_reason = CH_SWITCH_NORMAL;
developerd0c89452024-10-11 16:53:27 +0800409 else if (phy->mt76->offchannel ||
developer66e89bc2024-04-23 14:50:01 +0800410- phy->mt76->hw->conf.flags & IEEE80211_CONF_IDLE)
411+ phy->mt76->hw->conf.flags & IEEE80211_CONF_IDLE ||
412+ phy->scan_chan)
413 req.switch_reason = CH_SWITCH_SCAN_BYPASS_DPD;
414 else if (!cfg80211_reg_can_beacon(phy->mt76->hw->wiphy, chandef,
415 NL80211_IFTYPE_AP))
developerd0c89452024-10-11 16:53:27 +0800416diff --git a/mt7996/mmio.c b/mt7996/mmio.c
417index 14c70915..1fcca23c 100644
418--- a/mt7996/mmio.c
419+++ b/mt7996/mmio.c
420@@ -657,7 +657,7 @@ struct mt7996_dev *mt7996_mmio_probe(struct device *pdev,
421 .sta_add = mt7996_mac_sta_add,
422 .sta_remove = mt7996_mac_sta_remove,
423 .update_survey = mt7996_update_channel,
424- .set_channel = mt7996_set_channel,
425+ // .set_channel = mt7996_set_channel,
426 };
427 struct mt7996_dev *dev;
428 struct mt76_dev *mdev;
developer66e89bc2024-04-23 14:50:01 +0800429diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
developerd0c89452024-10-11 16:53:27 +0800430index 4e99830f..87b166aa 100644
developer66e89bc2024-04-23 14:50:01 +0800431--- a/mt7996/mt7996.h
432+++ b/mt7996/mt7996.h
developerd0c89452024-10-11 16:53:27 +0800433@@ -460,6 +460,13 @@ struct mt7996_phy {
developer66e89bc2024-04-23 14:50:01 +0800434 u8 pp_mode;
435 u16 punct_bitmap;
436
437+ /* for hw_scan */
438+ struct delayed_work scan_work;
439+ struct ieee80211_channel *scan_chan;
440+ struct cfg80211_scan_request *scan_req;
441+ struct ieee80211_vif *scan_vif;
442+ int scan_chan_idx;
443+
444 struct mt7996_scs_ctrl scs_ctrl;
445 u32 red_drop;
446
developerd0c89452024-10-11 16:53:27 +0800447@@ -811,7 +818,7 @@ int mt7996_mcu_add_obss_spr(struct mt7996_phy *phy, struct ieee80211_vif *vif,
developer66e89bc2024-04-23 14:50:01 +0800448 struct ieee80211_he_obss_pd *he_obss_pd);
449 int mt7996_mcu_add_rate_ctrl(struct mt7996_dev *dev, struct ieee80211_vif *vif,
450 struct ieee80211_sta *sta, bool changed);
developerd0c89452024-10-11 16:53:27 +0800451-int mt7996_set_channel(struct mt76_phy *mphy);
developer66e89bc2024-04-23 14:50:01 +0800452+int mt7996_set_channel(struct mt7996_phy *phy, struct cfg80211_chan_def *chandef);
453 int mt7996_mcu_set_chan_info(struct mt7996_phy *phy, u16 tag);
454 int mt7996_mcu_set_tx(struct mt7996_dev *dev, struct ieee80211_vif *vif);
455 int mt7996_mcu_set_fixed_rate_ctrl(struct mt7996_dev *dev,
developerd0c89452024-10-11 16:53:27 +0800456@@ -969,6 +976,8 @@ void mt7996_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q,
developer66e89bc2024-04-23 14:50:01 +0800457 struct sk_buff *skb, u32 *info);
458 bool mt7996_rx_check(struct mt76_dev *mdev, void *data, int len);
459 void mt7996_stats_work(struct work_struct *work);
460+void mt7996_scan_work(struct work_struct *work);
461+void mt7996_scan_complete(struct mt7996_phy *phy, bool aborted);
462 int mt76_dfs_start_rdd(struct mt7996_dev *dev, bool force);
463 int mt7996_dfs_init_radar_detector(struct mt7996_phy *phy);
464 void mt7996_set_stream_he_eht_caps(struct mt7996_phy *phy);
465--
developerd0c89452024-10-11 16:53:27 +08004662.45.2
developer66e89bc2024-04-23 14:50:01 +0800467