aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/mac80211/cfg.c8
-rw-r--r--net/mac80211/ieee80211_i.h4
-rw-r--r--net/mac80211/iface.c20
-rw-r--r--net/mac80211/wext.c9
4 files changed, 25 insertions, 16 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 6aa49ad172aa..ea0301025c15 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -84,22 +84,22 @@ static int ieee80211_change_iface(struct wiphy *wiphy, int ifindex,
84 struct net_device *dev; 84 struct net_device *dev;
85 enum ieee80211_if_types itype; 85 enum ieee80211_if_types itype;
86 struct ieee80211_sub_if_data *sdata; 86 struct ieee80211_sub_if_data *sdata;
87 int ret;
87 88
88 /* we're under RTNL */ 89 /* we're under RTNL */
89 dev = __dev_get_by_index(&init_net, ifindex); 90 dev = __dev_get_by_index(&init_net, ifindex);
90 if (!dev) 91 if (!dev)
91 return -ENODEV; 92 return -ENODEV;
92 93
93 if (netif_running(dev))
94 return -EBUSY;
95
96 itype = nl80211_type_to_mac80211_type(type); 94 itype = nl80211_type_to_mac80211_type(type);
97 if (itype == IEEE80211_IF_TYPE_INVALID) 95 if (itype == IEEE80211_IF_TYPE_INVALID)
98 return -EINVAL; 96 return -EINVAL;
99 97
100 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 98 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
101 99
102 ieee80211_if_change_type(sdata, itype); 100 ret = ieee80211_if_change_type(sdata, itype);
101 if (ret)
102 return ret;
103 103
104 if (ieee80211_vif_is_mesh(&sdata->vif) && params->mesh_id_len) 104 if (ieee80211_vif_is_mesh(&sdata->vif) && params->mesh_id_len)
105 ieee80211_if_sta_set_mesh_id(&sdata->u.sta, 105 ieee80211_if_sta_set_mesh_id(&sdata->u.sta,
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 35bcdfef9045..2146c0c436d2 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -930,8 +930,8 @@ void ieee80211_if_setup(struct net_device *dev);
930int ieee80211_if_add(struct ieee80211_local *local, const char *name, 930int ieee80211_if_add(struct ieee80211_local *local, const char *name,
931 struct net_device **new_dev, enum ieee80211_if_types type, 931 struct net_device **new_dev, enum ieee80211_if_types type,
932 struct vif_params *params); 932 struct vif_params *params);
933void ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata, 933int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata,
934 enum ieee80211_if_types type); 934 enum ieee80211_if_types type);
935void ieee80211_if_remove(struct net_device *dev); 935void ieee80211_if_remove(struct net_device *dev);
936void ieee80211_remove_interfaces(struct ieee80211_local *local); 936void ieee80211_remove_interfaces(struct ieee80211_local *local);
937 937
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 6cf121bebd7a..2e3adcb3ce23 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -138,9 +138,23 @@ static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata,
138 ieee80211_debugfs_add_netdev(sdata); 138 ieee80211_debugfs_add_netdev(sdata);
139} 139}
140 140
141void ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata, 141int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata,
142 enum ieee80211_if_types type) 142 enum ieee80211_if_types type)
143{ 143{
144 ASSERT_RTNL();
145
146 if (type == sdata->vif.type)
147 return 0;
148
149 /*
150 * We could, here, on changes between IBSS/STA/MESH modes,
151 * invoke an MLME function instead that disassociates etc.
152 * and goes into the requested mode.
153 */
154
155 if (netif_running(sdata->dev))
156 return -EBUSY;
157
144 /* Purge and reset type-dependent state. */ 158 /* Purge and reset type-dependent state. */
145 ieee80211_teardown_sdata(sdata->dev); 159 ieee80211_teardown_sdata(sdata->dev);
146 ieee80211_setup_sdata(sdata, type); 160 ieee80211_setup_sdata(sdata, type);
@@ -149,6 +163,8 @@ void ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata,
149 sdata->basic_rates = 0; 163 sdata->basic_rates = 0;
150 sdata->drop_unencrypted = 0; 164 sdata->drop_unencrypted = 0;
151 sdata->sequence = 0; 165 sdata->sequence = 0;
166
167 return 0;
152} 168}
153 169
154int ieee80211_if_add(struct ieee80211_local *local, const char *name, 170int ieee80211_if_add(struct ieee80211_local *local, const char *name,
diff --git a/net/mac80211/wext.c b/net/mac80211/wext.c
index f2fdd3342195..c041db9556c7 100644
--- a/net/mac80211/wext.c
+++ b/net/mac80211/wext.c
@@ -296,14 +296,7 @@ static int ieee80211_ioctl_siwmode(struct net_device *dev,
296 return -EINVAL; 296 return -EINVAL;
297 } 297 }
298 298
299 if (type == sdata->vif.type) 299 return ieee80211_if_change_type(sdata, type);
300 return 0;
301 if (netif_running(dev))
302 return -EBUSY;
303
304 ieee80211_if_change_type(sdata, type);
305
306 return 0;
307} 300}
308 301
309 302