summaryrefslogtreecommitdiff
path: root/net/wireless/mesh.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/wireless/mesh.c')
-rw-r--r--net/wireless/mesh.c61
1 files changed, 27 insertions, 34 deletions
diff --git a/net/wireless/mesh.c b/net/wireless/mesh.c
index eac5aa1419fc..2c6654075ca9 100644
--- a/net/wireless/mesh.c
+++ b/net/wireless/mesh.c
@@ -1,4 +1,8 @@
// SPDX-License-Identifier: GPL-2.0
+/*
+ * Portions
+ * Copyright (C) 2022-2024 Intel Corporation
+ */
#include <linux/ieee80211.h>
#include <linux/export.h>
#include <net/cfg80211.h>
@@ -78,6 +82,7 @@ const struct mesh_config default_mesh_config = {
.power_mode = NL80211_MESH_POWER_ACTIVE,
.dot11MeshAwakeWindowDuration = MESH_DEFAULT_AWAKE_WINDOW,
.plink_timeout = MESH_DEFAULT_PLINK_TIMEOUT,
+ .dot11MeshNolearn = false,
};
const struct mesh_setup default_mesh_setup = {
@@ -104,7 +109,7 @@ int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
BUILD_BUG_ON(IEEE80211_MAX_SSID_LEN != IEEE80211_MAX_MESH_ID_LEN);
- ASSERT_WDEV_LOCK(wdev);
+ lockdep_assert_wiphy(wdev->wiphy);
if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT)
return -EOPNOTSUPP;
@@ -113,7 +118,7 @@ int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
setup->is_secure)
return -EOPNOTSUPP;
- if (wdev->mesh_id_len)
+ if (wdev->u.mesh.id_len)
return -EALREADY;
if (!setup->mesh_id_len)
@@ -122,9 +127,12 @@ int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
if (!rdev->ops->join_mesh)
return -EOPNOTSUPP;
+ if (wdev->links[0].cac_started)
+ return -EBUSY;
+
if (!setup->chandef.chan) {
/* if no channel explicitly given, use preset channel */
- setup->chandef = wdev->preset_chandef;
+ setup->chandef = wdev->u.mesh.preset_chandef;
}
if (!setup->chandef.chan) {
@@ -167,7 +175,6 @@ int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
* basic rates
*/
if (!setup->basic_rates) {
- enum nl80211_bss_scan_width scan_width;
struct ieee80211_supported_band *sband =
rdev->wiphy.bands[setup->chandef.chan->band];
@@ -188,9 +195,7 @@ int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
}
}
} else {
- scan_width = cfg80211_chandef_to_scan_width(&setup->chandef);
- setup->basic_rates = ieee80211_mandatory_rates(sband,
- scan_width);
+ setup->basic_rates = ieee80211_mandatory_rates(sband);
}
}
@@ -208,10 +213,10 @@ int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
err = rdev_join_mesh(rdev, dev, conf, setup);
if (!err) {
- memcpy(wdev->ssid, setup->mesh_id, setup->mesh_id_len);
- wdev->mesh_id_len = setup->mesh_id_len;
- wdev->chandef = setup->chandef;
- wdev->beacon_interval = setup->beacon_interval;
+ memcpy(wdev->u.mesh.id, setup->mesh_id, setup->mesh_id_len);
+ wdev->u.mesh.id_len = setup->mesh_id_len;
+ wdev->u.mesh.chandef = setup->chandef;
+ wdev->u.mesh.beacon_interval = setup->beacon_interval;
}
return err;
@@ -240,25 +245,25 @@ int cfg80211_set_mesh_channel(struct cfg80211_registered_device *rdev,
err = rdev_libertas_set_mesh_channel(rdev, wdev->netdev,
chandef->chan);
if (!err)
- wdev->chandef = *chandef;
+ wdev->u.mesh.chandef = *chandef;
return err;
}
- if (wdev->mesh_id_len)
+ if (wdev->u.mesh.id_len)
return -EBUSY;
- wdev->preset_chandef = *chandef;
+ wdev->u.mesh.preset_chandef = *chandef;
return 0;
}
-int __cfg80211_leave_mesh(struct cfg80211_registered_device *rdev,
- struct net_device *dev)
+int cfg80211_leave_mesh(struct cfg80211_registered_device *rdev,
+ struct net_device *dev)
{
struct wireless_dev *wdev = dev->ieee80211_ptr;
int err;
- ASSERT_WDEV_LOCK(wdev);
+ lockdep_assert_wiphy(wdev->wiphy);
if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT)
return -EOPNOTSUPP;
@@ -266,31 +271,19 @@ int __cfg80211_leave_mesh(struct cfg80211_registered_device *rdev,
if (!rdev->ops->leave_mesh)
return -EOPNOTSUPP;
- if (!wdev->mesh_id_len)
+ if (!wdev->u.mesh.id_len)
return -ENOTCONN;
err = rdev_leave_mesh(rdev, dev);
if (!err) {
wdev->conn_owner_nlportid = 0;
- wdev->mesh_id_len = 0;
- wdev->beacon_interval = 0;
- memset(&wdev->chandef, 0, sizeof(wdev->chandef));
+ wdev->u.mesh.id_len = 0;
+ wdev->u.mesh.beacon_interval = 0;
+ memset(&wdev->u.mesh.chandef, 0,
+ sizeof(wdev->u.mesh.chandef));
rdev_set_qos_map(rdev, dev, NULL);
cfg80211_sched_dfs_chan_update(rdev);
}
return err;
}
-
-int cfg80211_leave_mesh(struct cfg80211_registered_device *rdev,
- struct net_device *dev)
-{
- struct wireless_dev *wdev = dev->ieee80211_ptr;
- int err;
-
- wdev_lock(wdev);
- err = __cfg80211_leave_mesh(rdev, dev);
- wdev_unlock(wdev);
-
- return err;
-}