Commit 636c5d488bc0b349e01cf5bfbf85588134af70a0

Authored by Johannes Berg
Committed by John W. Linville
1 parent e94e106831

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>

Showing 1 changed file with 27 additions and 17 deletions Side-by-side Diff

... ... @@ -257,20 +257,6 @@
257 257 case IEEE80211_IF_TYPE_WDS:
258 258 if (!is_valid_ether_addr(sdata->u.wds.remote_addr))
259 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 260 break;
275 261 case IEEE80211_IF_TYPE_VLAN:
276 262 if (!sdata->u.vlan.ap)
277 263  
... ... @@ -337,10 +323,8 @@
337 323 conf.type = sdata->vif.type;
338 324 conf.mac_addr = dev->dev_addr;
339 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 326 if (res)
343   - return res;
  327 + goto err_stop;
344 328  
345 329 ieee80211_if_config(dev);
346 330 ieee80211_reset_erp_info(dev);
347 331  
... ... @@ -353,9 +337,29 @@
353 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 358 if (local->open_count == 0) {
357 359 res = dev_open(local->mdev);
358 360 WARN_ON(res);
  361 + if (res)
  362 + goto err_del_interface;
359 363 tasklet_enable(&local->tx_pending_tasklet);
360 364 tasklet_enable(&local->tasklet);
361 365 }
... ... @@ -390,6 +394,12 @@
390 394 netif_start_queue(dev);
391 395  
392 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  
395 405 static int ieee80211_stop(struct net_device *dev)