]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - net/mac80211/cfg.c
Merge branch 'linus' into x86/ptemask
[linux-2.6-omap-h63xx.git] / net / mac80211 / cfg.c
index 5f8db5cab65dbd9fff2895d5cfe931844d0a500f..a9fce4afdf211b785753da1ea74f03546fc14d14 100644 (file)
@@ -14,7 +14,7 @@
 #include <net/cfg80211.h>
 #include "ieee80211_i.h"
 #include "cfg.h"
-#include "ieee80211_rate.h"
+#include "rate.h"
 #include "mesh.h"
 
 static enum ieee80211_if_types
@@ -33,6 +33,8 @@ nl80211_type_to_mac80211_type(enum nl80211_iftype type)
        case NL80211_IFTYPE_MESH_POINT:
                return IEEE80211_IF_TYPE_MESH_POINT;
 #endif
+       case NL80211_IFTYPE_WDS:
+               return IEEE80211_IF_TYPE_WDS;
        default:
                return IEEE80211_IF_TYPE_INVALID;
        }
@@ -135,6 +137,7 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
        struct sta_info *sta = NULL;
        enum ieee80211_key_alg alg;
        struct ieee80211_key *key;
+       int err;
 
        sdata = IEEE80211_DEV_TO_SUB_IF(dev);
 
@@ -157,17 +160,24 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
        if (!key)
                return -ENOMEM;
 
+       rcu_read_lock();
+
        if (mac_addr) {
                sta = sta_info_get(sdata->local, mac_addr);
                if (!sta) {
                        ieee80211_key_free(key);
-                       return -ENOENT;
+                       err = -ENOENT;
+                       goto out_unlock;
                }
        }
 
        ieee80211_key_link(key, sdata, sta);
 
-       return 0;
+       err = 0;
+ out_unlock:
+       rcu_read_unlock();
+
+       return err;
 }
 
 static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev,
@@ -179,28 +189,37 @@ static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev,
 
        sdata = IEEE80211_DEV_TO_SUB_IF(dev);
 
+       rcu_read_lock();
+
        if (mac_addr) {
+               ret = -ENOENT;
+
                sta = sta_info_get(sdata->local, mac_addr);
                if (!sta)
-                       return -ENOENT;
+                       goto out_unlock;
 
-               ret = 0;
                if (sta->key) {
                        ieee80211_key_free(sta->key);
                        WARN_ON(sta->key);
-               } else
-                       ret = -ENOENT;
+                       ret = 0;
+               }
 
-               return ret;
+               goto out_unlock;
        }
 
-       if (!sdata->keys[key_idx])
-               return -ENOENT;
+       if (!sdata->keys[key_idx]) {
+               ret = -ENOENT;
+               goto out_unlock;
+       }
 
        ieee80211_key_free(sdata->keys[key_idx]);
        WARN_ON(sdata->keys[key_idx]);
 
-       return 0;
+       ret = 0;
+ out_unlock:
+       rcu_read_unlock();
+
+       return ret;
 }
 
 static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev,
@@ -217,6 +236,8 @@ static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev,
        u16 iv16;
        int err = -ENOENT;
 
+       rcu_read_lock();
+
        if (mac_addr) {
                sta = sta_info_get(sdata->local, mac_addr);
                if (!sta)
@@ -280,6 +301,7 @@ static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev,
        err = 0;
 
  out:
+       rcu_read_unlock();
        return err;
 }
 
@@ -289,9 +311,13 @@ static int ieee80211_config_default_key(struct wiphy *wiphy,
 {
        struct ieee80211_sub_if_data *sdata;
 
+       rcu_read_lock();
+
        sdata = IEEE80211_DEV_TO_SUB_IF(dev);
        ieee80211_set_default_key(sdata, key_idx);
 
+       rcu_read_unlock();
+
        return 0;
 }
 
@@ -646,7 +672,7 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev,
        if (params->vlan) {
                sdata = IEEE80211_DEV_TO_SUB_IF(params->vlan);
 
-               if (sdata->vif.type != IEEE80211_IF_TYPE_VLAN ||
+               if (sdata->vif.type != IEEE80211_IF_TYPE_VLAN &&
                    sdata->vif.type != IEEE80211_IF_TYPE_AP)
                        return -EINVAL;
        } else
@@ -694,12 +720,18 @@ static int ieee80211_del_station(struct wiphy *wiphy, struct net_device *dev,
        struct sta_info *sta;
 
        if (mac) {
+               rcu_read_lock();
+
                /* XXX: get sta belonging to dev */
                sta = sta_info_get(local, mac);
-               if (!sta)
+               if (!sta) {
+                       rcu_read_unlock();
                        return -ENOENT;
+               }
 
                sta_info_unlink(&sta);
+               rcu_read_unlock();
+
                sta_info_destroy(sta);
        } else
                sta_info_flush(local, sdata);
@@ -716,17 +748,23 @@ static int ieee80211_change_station(struct wiphy *wiphy,
        struct sta_info *sta;
        struct ieee80211_sub_if_data *vlansdata;
 
+       rcu_read_lock();
+
        /* XXX: get sta belonging to dev */
        sta = sta_info_get(local, mac);
-       if (!sta)
+       if (!sta) {
+               rcu_read_unlock();
                return -ENOENT;
+       }
 
        if (params->vlan && params->vlan != sta->sdata->dev) {
                vlansdata = IEEE80211_DEV_TO_SUB_IF(params->vlan);
 
-               if (vlansdata->vif.type != IEEE80211_IF_TYPE_VLAN ||
-                   vlansdata->vif.type != IEEE80211_IF_TYPE_AP)
+               if (vlansdata->vif.type != IEEE80211_IF_TYPE_VLAN &&
+                   vlansdata->vif.type != IEEE80211_IF_TYPE_AP) {
+                       rcu_read_unlock();
                        return -EINVAL;
+               }
 
                sta->sdata = IEEE80211_DEV_TO_SUB_IF(params->vlan);
                ieee80211_send_layer2_update(sta);
@@ -734,6 +772,8 @@ static int ieee80211_change_station(struct wiphy *wiphy,
 
        sta_apply_parameters(local, sta, params);
 
+       rcu_read_unlock();
+
        return 0;
 }