diff options
author | David S. Miller <davem@davemloft.net> | 2013-04-01 13:36:50 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-04-01 13:36:50 -0400 |
commit | a210576cf891e9e6d2c238eabcf5c1286b1e7526 (patch) | |
tree | 0fa81a901cf628b25e6ee79057700cf39e59818a /net/mac80211 | |
parent | 7d4c04fc170087119727119074e72445f2bb192b (diff) | |
parent | 3658f3604066d5500ebd73a04084f127dc779441 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Conflicts:
net/mac80211/sta_info.c
net/wireless/core.h
Two minor conflicts in wireless. Overlapping additions of extern
declarations in net/wireless/core.h and a bug fix overlapping with
the addition of a boolean parameter to __ieee80211_key_free().
Signed-off-by: David S. Miller <davem@davemloft.net>
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 | ||||
-rw-r--r-- | net/mac80211/sta_info.c | 13 |
5 files changed, 49 insertions, 22 deletions
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index d85282f64405..7530c60fe502 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 5ac017f3fcd2..77b5710db241 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c | |||
@@ -1007,7 +1007,8 @@ void ieee80211_mesh_notify_scan_completed(struct ieee80211_local *local) | |||
1007 | 1007 | ||
1008 | rcu_read_lock(); | 1008 | rcu_read_lock(); |
1009 | list_for_each_entry_rcu(sdata, &local->interfaces, list) | 1009 | list_for_each_entry_rcu(sdata, &local->interfaces, list) |
1010 | if (ieee80211_vif_is_mesh(&sdata->vif)) | 1010 | if (ieee80211_vif_is_mesh(&sdata->vif) && |
1011 | ieee80211_sdata_running(sdata)) | ||
1011 | ieee80211_queue_work(&local->hw, &sdata->work); | 1012 | ieee80211_queue_work(&local->hw, &sdata->work); |
1012 | rcu_read_unlock(); | 1013 | rcu_read_unlock(); |
1013 | } | 1014 | } |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index fdc06e381c10..167158646593 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -3527,8 +3527,10 @@ void ieee80211_mlme_notify_scan_completed(struct ieee80211_local *local) | |||
3527 | 3527 | ||
3528 | /* Restart STA timers */ | 3528 | /* Restart STA timers */ |
3529 | rcu_read_lock(); | 3529 | rcu_read_lock(); |
3530 | list_for_each_entry_rcu(sdata, &local->interfaces, list) | 3530 | list_for_each_entry_rcu(sdata, &local->interfaces, list) { |
3531 | ieee80211_restart_sta_timer(sdata); | 3531 | if (ieee80211_sdata_running(sdata)) |
3532 | ieee80211_restart_sta_timer(sdata); | ||
3533 | } | ||
3532 | rcu_read_unlock(); | 3534 | rcu_read_unlock(); |
3533 | } | 3535 | } |
3534 | 3536 | ||
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; |
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 3644ad79688a..85458a28ffa0 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c | |||
@@ -771,6 +771,7 @@ int __must_check __sta_info_destroy(struct sta_info *sta) | |||
771 | struct ieee80211_local *local; | 771 | struct ieee80211_local *local; |
772 | struct ieee80211_sub_if_data *sdata; | 772 | struct ieee80211_sub_if_data *sdata; |
773 | int ret, i; | 773 | int ret, i; |
774 | bool have_key = false; | ||
774 | 775 | ||
775 | might_sleep(); | 776 | might_sleep(); |
776 | 777 | ||
@@ -798,14 +799,22 @@ int __must_check __sta_info_destroy(struct sta_info *sta) | |||
798 | list_del_rcu(&sta->list); | 799 | list_del_rcu(&sta->list); |
799 | 800 | ||
800 | mutex_lock(&local->key_mtx); | 801 | mutex_lock(&local->key_mtx); |
801 | for (i = 0; i < NUM_DEFAULT_KEYS; i++) | 802 | for (i = 0; i < NUM_DEFAULT_KEYS; i++) { |
802 | __ieee80211_key_free(key_mtx_dereference(local, sta->gtk[i]), | 803 | __ieee80211_key_free(key_mtx_dereference(local, sta->gtk[i]), |
803 | true); | 804 | true); |
804 | if (sta->ptk) | 805 | have_key = true; |
806 | } | ||
807 | if (sta->ptk) { | ||
805 | __ieee80211_key_free(key_mtx_dereference(local, sta->ptk), | 808 | __ieee80211_key_free(key_mtx_dereference(local, sta->ptk), |
806 | true); | 809 | true); |
810 | have_key = true; | ||
811 | } | ||
812 | |||
807 | mutex_unlock(&local->key_mtx); | 813 | mutex_unlock(&local->key_mtx); |
808 | 814 | ||
815 | if (!have_key) | ||
816 | synchronize_net(); | ||
817 | |||
809 | sta->dead = true; | 818 | sta->dead = true; |
810 | 819 | ||
811 | local->num_sta--; | 820 | local->num_sta--; |