diff options
-rw-r--r-- | net/mac80211/cfg.c | 8 | ||||
-rw-r--r-- | net/mac80211/ieee80211_i.h | 4 | ||||
-rw-r--r-- | net/mac80211/iface.c | 20 | ||||
-rw-r--r-- | net/mac80211/wext.c | 9 |
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); | |||
930 | int ieee80211_if_add(struct ieee80211_local *local, const char *name, | 930 | int 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); |
933 | void ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata, | 933 | int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata, |
934 | enum ieee80211_if_types type); | 934 | enum ieee80211_if_types type); |
935 | void ieee80211_if_remove(struct net_device *dev); | 935 | void ieee80211_if_remove(struct net_device *dev); |
936 | void ieee80211_remove_interfaces(struct ieee80211_local *local); | 936 | void 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 | ||
141 | void ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata, | 141 | int 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 | ||
154 | int ieee80211_if_add(struct ieee80211_local *local, const char *name, | 170 | int 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 | ||