mac80211: push interface checks down
authorJohannes Berg <johannes@sipsolutions.net>
Wed, 9 Jul 2008 12:40:36 +0000 (14:40 +0200)
committerJohn W. Linville <linville@tuxdriver.com>
Mon, 14 Jul 2008 18:30:07 +0000 (14:30 -0400)
This patch pushes the "netif_running()" and "same type as before"
checks down into ieee80211_if_change_type() to centralise the
logic instead of duplicating it for cfg80211 and wext.

Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
net/mac80211/cfg.c
net/mac80211/ieee80211_i.h
net/mac80211/iface.c
net/mac80211/wext.c

index 6aa49ad172aabc20cdf4e17712b0d07a4c25a68c..ea0301025c15d5605a7c22f0f8789d97c0f967f3 100644 (file)
@@ -84,22 +84,22 @@ static int ieee80211_change_iface(struct wiphy *wiphy, int ifindex,
        struct net_device *dev;
        enum ieee80211_if_types itype;
        struct ieee80211_sub_if_data *sdata;
+       int ret;
 
        /* we're under RTNL */
        dev = __dev_get_by_index(&init_net, ifindex);
        if (!dev)
                return -ENODEV;
 
-       if (netif_running(dev))
-               return -EBUSY;
-
        itype = nl80211_type_to_mac80211_type(type);
        if (itype == IEEE80211_IF_TYPE_INVALID)
                return -EINVAL;
 
        sdata = IEEE80211_DEV_TO_SUB_IF(dev);
 
-       ieee80211_if_change_type(sdata, itype);
+       ret = ieee80211_if_change_type(sdata, itype);
+       if (ret)
+               return ret;
 
        if (ieee80211_vif_is_mesh(&sdata->vif) && params->mesh_id_len)
                ieee80211_if_sta_set_mesh_id(&sdata->u.sta,
index 35bcdfef9045ff15d1bad2397f46608cb1732f02..2146c0c436d2eaecc44678e2f1bd6845bfbd42f4 100644 (file)
@@ -930,8 +930,8 @@ void ieee80211_if_setup(struct net_device *dev);
 int ieee80211_if_add(struct ieee80211_local *local, const char *name,
                     struct net_device **new_dev, enum ieee80211_if_types type,
                     struct vif_params *params);
-void ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata,
-                             enum ieee80211_if_types type);
+int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata,
+                            enum ieee80211_if_types type);
 void ieee80211_if_remove(struct net_device *dev);
 void ieee80211_remove_interfaces(struct ieee80211_local *local);
 
index 6cf121bebd7a03dee0afeb3f042f62845b9752ea..2e3adcb3ce235bb20a7b625193e01c8d557016e0 100644 (file)
@@ -138,9 +138,23 @@ static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata,
        ieee80211_debugfs_add_netdev(sdata);
 }
 
-void ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata,
-                             enum ieee80211_if_types type)
+int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata,
+                            enum ieee80211_if_types type)
 {
+       ASSERT_RTNL();
+
+       if (type == sdata->vif.type)
+               return 0;
+
+       /*
+        * We could, here, on changes between IBSS/STA/MESH modes,
+        * invoke an MLME function instead that disassociates etc.
+        * and goes into the requested mode.
+        */
+
+       if (netif_running(sdata->dev))
+               return -EBUSY;
+
        /* Purge and reset type-dependent state. */
        ieee80211_teardown_sdata(sdata->dev);
        ieee80211_setup_sdata(sdata, type);
@@ -149,6 +163,8 @@ void ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata,
        sdata->basic_rates = 0;
        sdata->drop_unencrypted = 0;
        sdata->sequence = 0;
+
+       return 0;
 }
 
 int ieee80211_if_add(struct ieee80211_local *local, const char *name,
index f2fdd334219525582b2d83c636824ef172c078fc..c041db9556c731acc2a54ed9fe695cf1a5b25c5f 100644 (file)
@@ -296,14 +296,7 @@ static int ieee80211_ioctl_siwmode(struct net_device *dev,
                return -EINVAL;
        }
 
-       if (type == sdata->vif.type)
-               return 0;
-       if (netif_running(dev))
-               return -EBUSY;
-
-       ieee80211_if_change_type(sdata, type);
-
-       return 0;
+       return ieee80211_if_change_type(sdata, type);
 }