Skip to content

Commit e411b81

Browse files
committed
wifi: mt76: add multi-radio support to scanning code
When scanning on a phy/vif combination that does not have an active link, create a temporary link in order to ensure that we have a valid wcid. Link: https://patch.msgid.link/[email protected] Signed-off-by: Felix Fietkau <[email protected]>
1 parent 716cc14 commit e411b81

File tree

3 files changed

+77
-2
lines changed

3 files changed

+77
-2
lines changed

drivers/net/wireless/mediatek/mt76/channel.c

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,20 @@
44
*/
55
#include "mt76.h"
66

7+
static struct mt76_vif_link *
8+
mt76_alloc_mlink(struct mt76_dev *dev, struct mt76_vif_data *mvif)
9+
{
10+
struct mt76_vif_link *mlink;
11+
12+
mlink = kzalloc(dev->drv->link_data_size, GFP_KERNEL);
13+
if (!mlink)
14+
return NULL;
15+
16+
mlink->mvif = mvif;
17+
18+
return mlink;
19+
}
20+
721
static int
822
mt76_phy_update_channel(struct mt76_phy *phy,
923
struct ieee80211_chanctx_conf *conf)
@@ -108,7 +122,7 @@ int mt76_assign_vif_chanctx(struct ieee80211_hw *hw,
108122

109123
mlink = mt76_vif_conf_link(dev, vif, link_conf);
110124
if (!mlink) {
111-
mlink = kzalloc(dev->drv->link_data_size, GFP_KERNEL);
125+
mlink = mt76_alloc_mlink(dev, mvif);
112126
if (!mlink) {
113127
ret = -ENOMEM;
114128
goto out;
@@ -248,3 +262,49 @@ int mt76_switch_vif_chanctx(struct ieee80211_hw *hw,
248262
return ret;
249263
}
250264
EXPORT_SYMBOL_GPL(mt76_switch_vif_chanctx);
265+
266+
struct mt76_vif_link *mt76_get_vif_phy_link(struct mt76_phy *phy,
267+
struct ieee80211_vif *vif)
268+
{
269+
struct mt76_vif_link *mlink = (struct mt76_vif_link *)vif->drv_priv;
270+
struct mt76_vif_data *mvif = mlink->mvif;
271+
struct mt76_dev *dev = phy->dev;
272+
int i, ret;
273+
274+
for (i = 0; i < ARRAY_SIZE(mvif->link); i++) {
275+
mlink = mt76_dereference(mvif->link[i], dev);
276+
if (!mlink)
277+
continue;
278+
279+
if (mt76_vif_link_phy(mlink) == phy)
280+
return mlink;
281+
}
282+
283+
if (!dev->drv->vif_link_add)
284+
return ERR_PTR(-EINVAL);
285+
286+
mlink = mt76_alloc_mlink(dev, mvif);
287+
if (!mlink)
288+
return ERR_PTR(-ENOMEM);
289+
290+
mlink->offchannel = true;
291+
ret = dev->drv->vif_link_add(phy, vif, &vif->bss_conf, mlink);
292+
if (ret) {
293+
kfree(mlink);
294+
return ERR_PTR(ret);
295+
}
296+
297+
return mlink;
298+
}
299+
300+
void mt76_put_vif_phy_link(struct mt76_phy *phy, struct ieee80211_vif *vif,
301+
struct mt76_vif_link *mlink)
302+
{
303+
struct mt76_dev *dev = phy->dev;
304+
305+
if (IS_ERR_OR_NULL(mlink) || !mlink->offchannel)
306+
return;
307+
308+
dev->drv->vif_link_remove(phy, vif, &vif->bss_conf, mlink);
309+
kfree(mlink);
310+
}

drivers/net/wireless/mediatek/mt76/mt76.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -777,6 +777,7 @@ struct mt76_vif_link {
777777
u8 basic_rates_idx;
778778
u8 mcast_rates_idx;
779779
u8 beacon_rates_idx;
780+
bool offchannel;
780781
struct ieee80211_chanctx_conf *ctx;
781782
struct mt76_wcid *wcid;
782783
struct mt76_vif_data *mvif;
@@ -942,6 +943,7 @@ struct mt76_dev {
942943
struct cfg80211_scan_request *req;
943944
struct ieee80211_channel *chan;
944945
struct ieee80211_vif *vif;
946+
struct mt76_vif_link *mlink;
945947
struct mt76_phy *phy;
946948
int chan_idx;
947949
} scan;
@@ -1570,6 +1572,10 @@ int mt76_set_channel(struct mt76_phy *phy, struct cfg80211_chan_def *chandef,
15701572
bool offchannel);
15711573
void mt76_scan_work(struct work_struct *work);
15721574
void mt76_abort_scan(struct mt76_dev *dev);
1575+
struct mt76_vif_link *mt76_get_vif_phy_link(struct mt76_phy *phy,
1576+
struct ieee80211_vif *vif);
1577+
void mt76_put_vif_phy_link(struct mt76_phy *phy, struct ieee80211_vif *vif,
1578+
struct mt76_vif_link *mlink);
15731579

15741580
/* usb */
15751581
static inline bool mt76u_urb_error(struct urb *urb)

drivers/net/wireless/mediatek/mt76/scan.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ static void mt76_scan_complete(struct mt76_dev *dev, bool abort)
1818

1919
if (dev->scan.chan && phy->main_chandef.chan)
2020
mt76_set_channel(phy, &phy->main_chandef, false);
21+
mt76_put_vif_phy_link(phy, dev->scan.vif, dev->scan.mlink);
2122
memset(&dev->scan, 0, sizeof(dev->scan));
2223
ieee80211_scan_completed(phy->hw, &info);
2324
}
@@ -33,7 +34,7 @@ mt76_scan_send_probe(struct mt76_dev *dev, struct cfg80211_ssid *ssid)
3334
{
3435
struct cfg80211_scan_request *req = dev->scan.req;
3536
struct ieee80211_vif *vif = dev->scan.vif;
36-
struct mt76_vif_link *mvif = (struct mt76_vif_link *)vif->drv_priv;
37+
struct mt76_vif_link *mvif = dev->scan.mlink;
3738
enum nl80211_band band = dev->scan.chan->band;
3839
struct mt76_phy *phy = dev->scan.phy;
3940
struct ieee80211_tx_info *info;
@@ -122,6 +123,7 @@ int mt76_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
122123
{
123124
struct mt76_phy *phy = hw->priv;
124125
struct mt76_dev *dev = phy->dev;
126+
struct mt76_vif_link *mlink;
125127
int ret = 0;
126128

127129
if (hw->wiphy->n_radio > 1) {
@@ -137,10 +139,17 @@ int mt76_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
137139
goto out;
138140
}
139141

142+
mlink = mt76_get_vif_phy_link(phy, vif);
143+
if (IS_ERR(mlink)) {
144+
ret = PTR_ERR(mlink);
145+
goto out;
146+
}
147+
140148
memset(&dev->scan, 0, sizeof(dev->scan));
141149
dev->scan.req = &req->req;
142150
dev->scan.vif = vif;
143151
dev->scan.phy = phy;
152+
dev->scan.mlink = mlink;
144153
ieee80211_queue_delayed_work(dev->phy.hw, &dev->scan_work, 0);
145154

146155
out:

0 commit comments

Comments
 (0)