diff options
author | John W. Linville <linville@tuxdriver.com> | 2013-03-29 16:41:36 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2013-03-29 16:41:36 -0400 |
commit | 9a574cd67a447059f9c14bbef47873315d7f7b35 (patch) | |
tree | 0ebb71d213d868d8884b1fa0e05b7393c66c665b /net/mac80211 | |
parent | 689b66cb53fbb5d567aa4e095eaa828aff73aef0 (diff) | |
parent | 2e1253d640eb7f8707d2591c93097c1e9f9c71d5 (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless
Conflicts:
net/mac80211/sta_info.c
net/wireless/core.h
Diffstat (limited to 'net/mac80211')
-rw-r--r-- | net/mac80211/iface.c | 35 | ||||
-rw-r--r-- | net/mac80211/mesh.c | 3 | ||||
-rw-r--r-- | net/mac80211/mlme.c | 6 | ||||
-rw-r--r-- | net/mac80211/rx.c | 14 |
4 files changed, 38 insertions, 20 deletions
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index d646e12e55a6..2a3c1e9bdf25 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
@@ -349,21 +349,19 @@ static void ieee80211_set_default_queues(struct ieee80211_sub_if_data *sdata) | |||
349 | static int ieee80211_add_virtual_monitor(struct ieee80211_local *local) | 349 | static int ieee80211_add_virtual_monitor(struct ieee80211_local *local) |
350 | { | 350 | { |
351 | struct ieee80211_sub_if_data *sdata; | 351 | struct ieee80211_sub_if_data *sdata; |
352 | int ret = 0; | 352 | int ret; |
353 | 353 | ||
354 | if (!(local->hw.flags & IEEE80211_HW_WANT_MONITOR_VIF)) | 354 | if (!(local->hw.flags & IEEE80211_HW_WANT_MONITOR_VIF)) |
355 | return 0; | 355 | return 0; |
356 | 356 | ||
357 | mutex_lock(&local->iflist_mtx); | 357 | ASSERT_RTNL(); |
358 | 358 | ||
359 | if (local->monitor_sdata) | 359 | if (local->monitor_sdata) |
360 | goto out_unlock; | 360 | return 0; |
361 | 361 | ||
362 | sdata = kzalloc(sizeof(*sdata) + local->hw.vif_data_size, GFP_KERNEL); | 362 | sdata = kzalloc(sizeof(*sdata) + local->hw.vif_data_size, GFP_KERNEL); |
363 | if (!sdata) { | 363 | if (!sdata) |
364 | ret = -ENOMEM; | 364 | return -ENOMEM; |
365 | goto out_unlock; | ||
366 | } | ||
367 | 365 | ||
368 | /* set up data */ | 366 | /* set up data */ |
369 | sdata->local = local; | 367 | sdata->local = local; |
@@ -377,13 +375,13 @@ static int ieee80211_add_virtual_monitor(struct ieee80211_local *local) | |||
377 | if (WARN_ON(ret)) { | 375 | if (WARN_ON(ret)) { |
378 | /* ok .. stupid driver, it asked for this! */ | 376 | /* ok .. stupid driver, it asked for this! */ |
379 | kfree(sdata); | 377 | kfree(sdata); |
380 | goto out_unlock; | 378 | return ret; |
381 | } | 379 | } |
382 | 380 | ||
383 | ret = ieee80211_check_queues(sdata); | 381 | ret = ieee80211_check_queues(sdata); |
384 | if (ret) { | 382 | if (ret) { |
385 | kfree(sdata); | 383 | kfree(sdata); |
386 | goto out_unlock; | 384 | return ret; |
387 | } | 385 | } |
388 | 386 | ||
389 | ret = ieee80211_vif_use_channel(sdata, &local->monitor_chandef, | 387 | ret = ieee80211_vif_use_channel(sdata, &local->monitor_chandef, |
@@ -391,13 +389,14 @@ static int ieee80211_add_virtual_monitor(struct ieee80211_local *local) | |||
391 | if (ret) { | 389 | if (ret) { |
392 | drv_remove_interface(local, sdata); | 390 | drv_remove_interface(local, sdata); |
393 | kfree(sdata); | 391 | kfree(sdata); |
394 | goto out_unlock; | 392 | return ret; |
395 | } | 393 | } |
396 | 394 | ||
395 | mutex_lock(&local->iflist_mtx); | ||
397 | rcu_assign_pointer(local->monitor_sdata, sdata); | 396 | rcu_assign_pointer(local->monitor_sdata, sdata); |
398 | out_unlock: | ||
399 | mutex_unlock(&local->iflist_mtx); | 397 | mutex_unlock(&local->iflist_mtx); |
400 | return ret; | 398 | |
399 | return 0; | ||
401 | } | 400 | } |
402 | 401 | ||
403 | static void ieee80211_del_virtual_monitor(struct ieee80211_local *local) | 402 | static void ieee80211_del_virtual_monitor(struct ieee80211_local *local) |
@@ -407,14 +406,20 @@ static void ieee80211_del_virtual_monitor(struct ieee80211_local *local) | |||
407 | if (!(local->hw.flags & IEEE80211_HW_WANT_MONITOR_VIF)) | 406 | if (!(local->hw.flags & IEEE80211_HW_WANT_MONITOR_VIF)) |
408 | return; | 407 | return; |
409 | 408 | ||
409 | ASSERT_RTNL(); | ||
410 | |||
410 | mutex_lock(&local->iflist_mtx); | 411 | mutex_lock(&local->iflist_mtx); |
411 | 412 | ||
412 | sdata = rcu_dereference_protected(local->monitor_sdata, | 413 | sdata = rcu_dereference_protected(local->monitor_sdata, |
413 | lockdep_is_held(&local->iflist_mtx)); | 414 | lockdep_is_held(&local->iflist_mtx)); |
414 | if (!sdata) | 415 | if (!sdata) { |
415 | goto out_unlock; | 416 | mutex_unlock(&local->iflist_mtx); |
417 | return; | ||
418 | } | ||
416 | 419 | ||
417 | rcu_assign_pointer(local->monitor_sdata, NULL); | 420 | rcu_assign_pointer(local->monitor_sdata, NULL); |
421 | mutex_unlock(&local->iflist_mtx); | ||
422 | |||
418 | synchronize_net(); | 423 | synchronize_net(); |
419 | 424 | ||
420 | ieee80211_vif_release_channel(sdata); | 425 | ieee80211_vif_release_channel(sdata); |
@@ -422,8 +427,6 @@ static void ieee80211_del_virtual_monitor(struct ieee80211_local *local) | |||
422 | drv_remove_interface(local, sdata); | 427 | drv_remove_interface(local, sdata); |
423 | 428 | ||
424 | kfree(sdata); | 429 | kfree(sdata); |
425 | out_unlock: | ||
426 | mutex_unlock(&local->iflist_mtx); | ||
427 | } | 430 | } |
428 | 431 | ||
429 | /* | 432 | /* |
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index aead5410c622..123a300cef57 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c | |||
@@ -1004,7 +1004,8 @@ void ieee80211_mesh_notify_scan_completed(struct ieee80211_local *local) | |||
1004 | 1004 | ||
1005 | rcu_read_lock(); | 1005 | rcu_read_lock(); |
1006 | list_for_each_entry_rcu(sdata, &local->interfaces, list) | 1006 | list_for_each_entry_rcu(sdata, &local->interfaces, list) |
1007 | if (ieee80211_vif_is_mesh(&sdata->vif)) | 1007 | if (ieee80211_vif_is_mesh(&sdata->vif) && |
1008 | ieee80211_sdata_running(sdata)) | ||
1008 | ieee80211_queue_work(&local->hw, &sdata->work); | 1009 | ieee80211_queue_work(&local->hw, &sdata->work); |
1009 | rcu_read_unlock(); | 1010 | rcu_read_unlock(); |
1010 | } | 1011 | } |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 4d383a93ea73..e06dbbf8cb4c 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -3531,8 +3531,10 @@ void ieee80211_mlme_notify_scan_completed(struct ieee80211_local *local) | |||
3531 | 3531 | ||
3532 | /* Restart STA timers */ | 3532 | /* Restart STA timers */ |
3533 | rcu_read_lock(); | 3533 | rcu_read_lock(); |
3534 | list_for_each_entry_rcu(sdata, &local->interfaces, list) | 3534 | list_for_each_entry_rcu(sdata, &local->interfaces, list) { |
3535 | ieee80211_restart_sta_timer(sdata); | 3535 | if (ieee80211_sdata_running(sdata)) |
3536 | ieee80211_restart_sta_timer(sdata); | ||
3537 | } | ||
3536 | rcu_read_unlock(); | 3538 | rcu_read_unlock(); |
3537 | } | 3539 | } |
3538 | 3540 | ||
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 5b4492af4e85..2528b5a4d6d4 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -2666,7 +2666,19 @@ ieee80211_rx_h_action_return(struct ieee80211_rx_data *rx) | |||
2666 | 2666 | ||
2667 | memset(nskb->cb, 0, sizeof(nskb->cb)); | 2667 | memset(nskb->cb, 0, sizeof(nskb->cb)); |
2668 | 2668 | ||
2669 | ieee80211_tx_skb(rx->sdata, nskb); | 2669 | if (rx->sdata->vif.type == NL80211_IFTYPE_P2P_DEVICE) { |
2670 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(nskb); | ||
2671 | |||
2672 | info->flags = IEEE80211_TX_CTL_TX_OFFCHAN | | ||
2673 | IEEE80211_TX_INTFL_OFFCHAN_TX_OK | | ||
2674 | IEEE80211_TX_CTL_NO_CCK_RATE; | ||
2675 | if (local->hw.flags & IEEE80211_HW_QUEUE_CONTROL) | ||
2676 | info->hw_queue = | ||
2677 | local->hw.offchannel_tx_hw_queue; | ||
2678 | } | ||
2679 | |||
2680 | __ieee80211_tx_skb_tid_band(rx->sdata, nskb, 7, | ||
2681 | status->band); | ||
2670 | } | 2682 | } |
2671 | dev_kfree_skb(rx->skb); | 2683 | dev_kfree_skb(rx->skb); |
2672 | return RX_QUEUED; | 2684 | return RX_QUEUED; |