Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=42613db7605a68a70f97513137392bda9b27bb9e
Commit:     42613db7605a68a70f97513137392bda9b27bb9e
Parent:     47f0c502209056da728e6a306a43d5e19a37f4fa
Author:     Johannes Berg <[EMAIL PROTECTED]>
AuthorDate: Fri Sep 28 21:52:27 2007 +0200
Committer:  David S. Miller <[EMAIL PROTECTED]>
CommitDate: Wed Oct 10 16:54:20 2007 -0700

    [MAC80211]: implement cfg80211's change_interface hook
    
    This implements the cfg80211 change_interface hook that changes the
    type of an interface and cleans up the code a bit.
    
    Signed-off-by: Johannes Berg <[EMAIL PROTECTED]>
    Signed-off-by: John W. Linville <[EMAIL PROTECTED]>
    Signed-off-by: David S. Miller <[EMAIL PROTECTED]>
---
 net/mac80211/cfg.c |   75 +++++++++++++++++++++++++++++++++++++++------------
 1 files changed, 57 insertions(+), 18 deletions(-)

diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 6981ba1..9e2bc1f 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -13,31 +13,35 @@
 #include "ieee80211_i.h"
 #include "cfg.h"
 
+static enum ieee80211_if_types
+nl80211_type_to_mac80211_type(enum nl80211_iftype type)
+{
+       switch (type) {
+       case NL80211_IFTYPE_UNSPECIFIED:
+               return IEEE80211_IF_TYPE_STA;
+       case NL80211_IFTYPE_ADHOC:
+               return IEEE80211_IF_TYPE_IBSS;
+       case NL80211_IFTYPE_STATION:
+               return IEEE80211_IF_TYPE_STA;
+       case NL80211_IFTYPE_MONITOR:
+               return IEEE80211_IF_TYPE_MNTR;
+       default:
+               return IEEE80211_IF_TYPE_INVALID;
+       }
+}
+
 static int ieee80211_add_iface(struct wiphy *wiphy, char *name,
                               enum nl80211_iftype type)
 {
        struct ieee80211_local *local = wiphy_priv(wiphy);
-       int itype;
+       enum ieee80211_if_types itype;
 
        if (unlikely(local->reg_state != IEEE80211_DEV_REGISTERED))
                return -ENODEV;
 
-       switch (type) {
-       case NL80211_IFTYPE_UNSPECIFIED:
-               itype = IEEE80211_IF_TYPE_STA;
-               break;
-       case NL80211_IFTYPE_ADHOC:
-               itype = IEEE80211_IF_TYPE_IBSS;
-               break;
-       case NL80211_IFTYPE_STATION:
-               itype = IEEE80211_IF_TYPE_STA;
-               break;
-       case NL80211_IFTYPE_MONITOR:
-               itype = IEEE80211_IF_TYPE_MNTR;
-               break;
-       default:
+       itype = nl80211_type_to_mac80211_type(type);
+       if (itype == IEEE80211_IF_TYPE_INVALID)
                return -EINVAL;
-       }
 
        return ieee80211_if_add(local->mdev, name, NULL, itype);
 }
@@ -51,17 +55,52 @@ static int ieee80211_del_iface(struct wiphy *wiphy, int 
ifindex)
        if (unlikely(local->reg_state != IEEE80211_DEV_REGISTERED))
                return -ENODEV;
 
-       dev = dev_get_by_index(&init_net, ifindex);
+       /* we're under RTNL */
+       dev = __dev_get_by_index(&init_net, ifindex);
        if (!dev)
                return 0;
 
        name = dev->name;
-       dev_put(dev);
 
        return ieee80211_if_remove(local->mdev, name, -1);
 }
 
+static int ieee80211_change_iface(struct wiphy *wiphy, int ifindex,
+                                 enum nl80211_iftype type)
+{
+       struct ieee80211_local *local = wiphy_priv(wiphy);
+       struct net_device *dev;
+       enum ieee80211_if_types itype;
+       struct ieee80211_sub_if_data *sdata;
+
+       if (unlikely(local->reg_state != IEEE80211_DEV_REGISTERED))
+               return -ENODEV;
+
+       /* 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);
+
+        if (sdata->type == IEEE80211_IF_TYPE_VLAN)
+               return -EOPNOTSUPP;
+
+       ieee80211_if_reinit(dev);
+       ieee80211_if_set_type(dev, itype);
+
+       return 0;
+}
+
 struct cfg80211_ops mac80211_config_ops = {
        .add_virtual_intf = ieee80211_add_iface,
        .del_virtual_intf = ieee80211_del_iface,
+       .change_virtual_intf = ieee80211_change_iface,
 };
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to