]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - net/wireless/mesh.c
Merge branch 'kmap_atomic' of git://github.com/congwang/linux
[karo-tx-linux.git] / net / wireless / mesh.c
index 3b73b07486cfb34197f653f1e4896e1cb56c6173..c384e77ff77a4e8c2f62398c7559361c5033ad03 100644 (file)
@@ -155,10 +155,16 @@ int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
                                          setup->channel_type))
                return -EINVAL;
 
+       err = cfg80211_can_use_chan(rdev, wdev, setup->channel,
+                                   CHAN_MODE_SHARED);
+       if (err)
+               return err;
+
        err = rdev->ops->join_mesh(&rdev->wiphy, dev, conf, setup);
        if (!err) {
                memcpy(wdev->ssid, setup->mesh_id, setup->mesh_id_len);
                wdev->mesh_id_len = setup->mesh_id_len;
+               wdev->channel = setup->channel;
        }
 
        return err;
@@ -172,9 +178,11 @@ int cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
        struct wireless_dev *wdev = dev->ieee80211_ptr;
        int err;
 
+       mutex_lock(&rdev->devlist_mtx);
        wdev_lock(wdev);
        err = __cfg80211_join_mesh(rdev, dev, setup, conf);
        wdev_unlock(wdev);
+       mutex_unlock(&rdev->devlist_mtx);
 
        return err;
 }
@@ -184,6 +192,7 @@ int cfg80211_set_mesh_freq(struct cfg80211_registered_device *rdev,
                           enum nl80211_channel_type channel_type)
 {
        struct ieee80211_channel *channel;
+       int err;
 
        channel = rdev_freq_to_chan(rdev, freq, channel_type);
        if (!channel || !cfg80211_can_beacon_sec_chan(&rdev->wiphy,
@@ -205,9 +214,19 @@ int cfg80211_set_mesh_freq(struct cfg80211_registered_device *rdev,
 
                if (!netif_running(wdev->netdev))
                        return -ENETDOWN;
-               return rdev->ops->libertas_set_mesh_channel(&rdev->wiphy,
-                                                           wdev->netdev,
-                                                           channel);
+
+               err = cfg80211_can_use_chan(rdev, wdev, channel,
+                                           CHAN_MODE_SHARED);
+               if (err)
+                       return err;
+
+               err = rdev->ops->libertas_set_mesh_channel(&rdev->wiphy,
+                                                          wdev->netdev,
+                                                          channel);
+               if (!err)
+                       wdev->channel = channel;
+
+               return err;
        }
 
        if (wdev->mesh_id_len)
@@ -249,8 +268,11 @@ static int __cfg80211_leave_mesh(struct cfg80211_registered_device *rdev,
                return -ENOTCONN;
 
        err = rdev->ops->leave_mesh(&rdev->wiphy, dev);
-       if (!err)
+       if (!err) {
                wdev->mesh_id_len = 0;
+               wdev->channel = NULL;
+       }
+
        return err;
 }