Commit 636c5d488bc0b349e01cf5bfbf85588134af70a0
Committed by
John W. Linville
1 parent
e94e106831
Exists in
master
and in
7 other branches
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
net/mac80211/main.c
... | ... | @@ -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) |