summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--net/mac802154/ieee802154_dev.c25
-rw-r--r--net/mac802154/mac802154.h1
2 files changed, 26 insertions, 0 deletions
diff --git a/net/mac802154/ieee802154_dev.c b/net/mac802154/ieee802154_dev.c
index 10cdb091b775..e7aa76445fe1 100644
--- a/net/mac802154/ieee802154_dev.c
+++ b/net/mac802154/ieee802154_dev.c
@@ -36,9 +36,28 @@
int mac802154_slave_open(struct net_device *dev)
{
struct mac802154_sub_if_data *priv = netdev_priv(dev);
+ struct mac802154_sub_if_data *subif;
struct mac802154_priv *ipriv = priv->hw;
int res = 0;
+ ASSERT_RTNL();
+
+ if (priv->type == IEEE802154_DEV_WPAN) {
+ mutex_lock(&priv->hw->slaves_mtx);
+ list_for_each_entry(subif, &priv->hw->slaves, list) {
+ if (subif != priv && subif->type == priv->type &&
+ subif->running) {
+ mutex_unlock(&priv->hw->slaves_mtx);
+ return -EBUSY;
+ }
+ }
+ mutex_unlock(&priv->hw->slaves_mtx);
+ }
+
+ mutex_lock(&priv->hw->slaves_mtx);
+ priv->running = true;
+ mutex_unlock(&priv->hw->slaves_mtx);
+
if (ipriv->open_count++ == 0) {
res = ipriv->ops->start(&ipriv->hw);
WARN_ON(res);
@@ -69,8 +88,14 @@ int mac802154_slave_close(struct net_device *dev)
struct mac802154_sub_if_data *priv = netdev_priv(dev);
struct mac802154_priv *ipriv = priv->hw;
+ ASSERT_RTNL();
+
netif_stop_queue(dev);
+ mutex_lock(&priv->hw->slaves_mtx);
+ priv->running = false;
+ mutex_unlock(&priv->hw->slaves_mtx);
+
if (!--ipriv->open_count)
ipriv->ops->stop(&ipriv->hw);
diff --git a/net/mac802154/mac802154.h b/net/mac802154/mac802154.h
index 4619486f1da2..f40522ef288c 100644
--- a/net/mac802154/mac802154.h
+++ b/net/mac802154/mac802154.h
@@ -71,6 +71,7 @@ struct mac802154_sub_if_data {
struct net_device *dev;
int type;
+ bool running;
spinlock_t mib_lock;