aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2008-04-24 08:18:37 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-04-30 20:34:26 -0400
commit636c5d488bc0b349e01cf5bfbf85588134af70a0 (patch)
treec1d823f345b1b6f23cd93a3c1eb6eef0ae04ae30 /net/mac80211
parente94e106831403d5028e7bb73c3163951134de1ba (diff)
mac80211: insert WDS peer after adding interface
This reorders the open code so that WDS peer STA info entries are added after the corresponding interface is added to the driver so that driver callbacks aren't invoked out of order. Also make any master device startup fatal. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211')
-rw-r--r--net/mac80211/main.c44
1 files changed, 27 insertions, 17 deletions
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index ab952fff1811..9ad4e3631b6b 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -257,20 +257,6 @@ static int ieee80211_open(struct net_device *dev)
257 case IEEE80211_IF_TYPE_WDS: 257 case IEEE80211_IF_TYPE_WDS:
258 if (!is_valid_ether_addr(sdata->u.wds.remote_addr)) 258 if (!is_valid_ether_addr(sdata->u.wds.remote_addr))
259 return -ENOLINK; 259 return -ENOLINK;
260
261 /* Create STA entry for the WDS peer */
262 sta = sta_info_alloc(sdata, sdata->u.wds.remote_addr,
263 GFP_KERNEL);
264 if (!sta)
265 return -ENOMEM;
266
267 sta->flags |= WLAN_STA_AUTHORIZED;
268
269 res = sta_info_insert(sta);
270 if (res) {
271 /* STA has been freed */
272 return res;
273 }
274 break; 260 break;
275 case IEEE80211_IF_TYPE_VLAN: 261 case IEEE80211_IF_TYPE_VLAN:
276 if (!sdata->u.vlan.ap) 262 if (!sdata->u.vlan.ap)
@@ -337,10 +323,8 @@ static int ieee80211_open(struct net_device *dev)
337 conf.type = sdata->vif.type; 323 conf.type = sdata->vif.type;
338 conf.mac_addr = dev->dev_addr; 324 conf.mac_addr = dev->dev_addr;
339 res = local->ops->add_interface(local_to_hw(local), &conf); 325 res = local->ops->add_interface(local_to_hw(local), &conf);
340 if (res && !local->open_count && local->ops->stop)
341 local->ops->stop(local_to_hw(local));
342 if (res) 326 if (res)
343 return res; 327 goto err_stop;
344 328
345 ieee80211_if_config(dev); 329 ieee80211_if_config(dev);
346 ieee80211_reset_erp_info(dev); 330 ieee80211_reset_erp_info(dev);
@@ -353,9 +337,29 @@ static int ieee80211_open(struct net_device *dev)
353 netif_carrier_on(dev); 337 netif_carrier_on(dev);
354 } 338 }
355 339
340 if (sdata->vif.type == IEEE80211_IF_TYPE_WDS) {
341 /* Create STA entry for the WDS peer */
342 sta = sta_info_alloc(sdata, sdata->u.wds.remote_addr,
343 GFP_KERNEL);
344 if (!sta) {
345 res = -ENOMEM;
346 goto err_del_interface;
347 }
348
349 sta->flags |= WLAN_STA_AUTHORIZED;
350
351 res = sta_info_insert(sta);
352 if (res) {
353 /* STA has been freed */
354 goto err_del_interface;
355 }
356 }
357
356 if (local->open_count == 0) { 358 if (local->open_count == 0) {
357 res = dev_open(local->mdev); 359 res = dev_open(local->mdev);
358 WARN_ON(res); 360 WARN_ON(res);
361 if (res)
362 goto err_del_interface;
359 tasklet_enable(&local->tx_pending_tasklet); 363 tasklet_enable(&local->tx_pending_tasklet);
360 tasklet_enable(&local->tasklet); 364 tasklet_enable(&local->tasklet);
361 } 365 }
@@ -390,6 +394,12 @@ static int ieee80211_open(struct net_device *dev)
390 netif_start_queue(dev); 394 netif_start_queue(dev);
391 395
392 return 0; 396 return 0;
397 err_del_interface:
398 local->ops->remove_interface(local_to_hw(local), &conf);
399 err_stop:
400 if (!local->open_count && local->ops->stop)
401 local->ops->stop(local_to_hw(local));
402 return res;
393} 403}
394 404
395static int ieee80211_stop(struct net_device *dev) 405static int ieee80211_stop(struct net_device *dev)